Way to know bytes of an int in Python [with bits class thrown in]

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • dansolo
    New Member
    • May 2007
    • 7

    Way to know bytes of an int in Python [with bits class thrown in]

    Hi,

    I need to know the byte which a number is made of. For example, let's suppose I have

    i = 3000

    I would like to know if there is a way to get the single byte of the number (0x0B and 0xB8).

    Thanks in advance,
    Daniele
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    Originally posted by dansolo
    Hi,

    I need to know the byte which a number is made of. For example, let's suppose I have

    i = 3000

    I would like to know if there is a way to get the single byte of the number (0x0B and 0xB8).

    Thanks in advance,
    Daniele
    Code:
    >>> aHex = hex(3000) # call built-in function to convert to hex
    >>> print aHex
    0xbb8
    >>> bytes = aHex[2:].zfill(4) # slice off the '0x'
    >>> print bytes
    0bb8
    >>> highByte = '0x%s' % bytes[0:2] #reformat with '0x' added to just the high byte
    >>> print highByte
    0x0b
    >>>
    Let's see if you can get the low byte. We're here to help.

    Comment

    • dshimer
      Recognized Expert New Member
      • Dec 2006
      • 136

      #3
      Just a curiosity but is there any built-in that would convert to binary? For example:
      3000='101110111 000'

      Comment

      • dansolo
        New Member
        • May 2007
        • 7

        #4
        First of all thanks,

        the lowbyte comes from

        lowByte = '0x%s' % bytes[2:4]

        I've found also another solution:
        [CODE=python]
        # mod edit # added for completeness #
        import struct
        ############### ############### ##
        def getByteLength(s elf, length):
        temp = struct.pack('!h ', length)
        byteList = [firstLength, secondLength] = struct.unpack(' BB', temp)
        return list(byteList)
        [/CODE]
        to obtain a list in which the elements are the needed bytes
        Last edited by bartonc; May 18 '07, 04:46 PM. Reason: added [code][/code] tags

        Comment

        • bartonc
          Recognized Expert Expert
          • Sep 2006
          • 6478

          #5
          Originally posted by dshimer
          Just a curiosity but is there any built-in that would convert to binary? For example:
          3000='101110111 000'
          While it's true that
          >>> int('101', 2)
          5
          >>>
          There is no bit or byte type to call for conversion to base 2.

          Comment

          • bartonc
            Recognized Expert Expert
            • Sep 2006
            • 6478

            #6
            Originally posted by bartonc
            While it's true that
            >>> int('101', 2)
            5
            >>>
            There is no bit or byte type to call for conversion to base 2.
            How 'bout this little goodie:[CODE=python]def Byte2Bits(value ):
            # Create a list of bits to convert big endian wise
            data = []
            outStr = ""
            for i in range(8):
            value, rem = divmod(value, 2)
            data.insert(0, rem)

            for pos, i in enumerate(data) :
            if not (pos % 4):
            outStr += " "
            outStr += str(i)
            return outStr


            def Base2Repr(value ):
            # Create a list of bytes to convert big endian wise
            data = []
            outStr = ""
            while value:
            value, rem = divmod(value, 256)
            data.insert(0, rem)
            for i in data:
            outStr += Byte2Bits(i)
            return outStr[1:]


            class bits(object):
            def __init__(self, value):
            self.value = value

            def __repr__(self):
            return Base2Repr(self. value)



            if __name__ == "__main__":
            b = bits(0xf5a5)
            print b
            [/CODE]
            1111 0101 1010 0101

            Comment

            • bvdet
              Recognized Expert Specialist
              • Oct 2006
              • 2851

              #7
              Originally posted by dshimer
              Just a curiosity but is there any built-in that would convert to binary? For example:
              3000='101110111 000'
              I don't think so, but I made this up:[code=Python]def ConvDecToBaseVa r(num, base):
              if base > 10 or base < 2:
              raise ValueError, 'The base number must be between 2 and 10.'
              if num == 0: return 0
              ans = ''
              while num != 0:
              num, rem = divmod(num, base)
              ans = str(rem)+ans
              return int(ans)

              '''
              >>> ConvDecToBaseVa r(3000,2)
              101110111000L
              >>>
              '''[/code]

              Comment

              • dshimer
                Recognized Expert New Member
                • Dec 2006
                • 136

                #8
                I was just curious about a built-in but that is absolutely Beautiful!

                Comment

                • bartonc
                  Recognized Expert Expert
                  • Sep 2006
                  • 6478

                  #9
                  Originally posted by dshimer
                  I was just curious about a built-in but that is absolutely Beautiful!
                  It's beautiful, all right (ain't BV good). But what about nibble formatting?

                  Comment

                  • bvdet
                    Recognized Expert Specialist
                    • Oct 2006
                    • 2851

                    #10
                    I was intrigued by a problem Motoma tackled and posted to Python Articles.

                    Comment

                    • ghostdog74
                      Recognized Expert Contributor
                      • Apr 2006
                      • 511

                      #11
                      Originally posted by dshimer
                      Just a curiosity but is there any built-in that would convert to binary? For example:
                      3000='101110111 000'
                      Code:
                      def dectobin(number):
                          if number < 1: return ""
                          else:return dectobin(number/2) + str(number & 1)

                      Comment

                      • bartonc
                        Recognized Expert Expert
                        • Sep 2006
                        • 6478

                        #12
                        Originally posted by ghostdog74
                        Code:
                        def dectobin(number):
                            if number < 1: return ""
                            else:return dectobin(number/2) + str(number & 1)
                        VERY nice, GD. So, let's see: If <edit: this isn't right [the integer division of number by 2]> number is odd, then the next [L]MSb is a one... Am I getting that right? And where/how did you dream up that algorithm?
                        Last edited by bartonc; May 19 '07, 03:10 AM. Reason: re-thinking

                        Comment

                        • ghostdog74
                          Recognized Expert Contributor
                          • Apr 2006
                          • 511

                          #13
                          Originally posted by bartonc
                          VERY nice, GD. So, let's see: If <edit: this isn't right [the integer division of number by 2]> number is odd, then the next [L]MSb is a one... Am I getting that right? And where/how did you dream up that algorithm?
                          the & operator is just to test the LSB of binary division.
                          say for example 14 divide by 2. in binary division of these 2 numbers,
                          1110 divide by 10 , as you slowly progress, you will reach the LSB and it will always be 0 or 1.
                          In & operations, a true and true is a true. So if the LSB is 0, & with 1 will be 0. (tested no remainder) . if LSB is 1, & with 1 is a 1, so there's remainder.

                          ( in this case, 14/2 is remainder 0, so the bit tested is 0 )
                          and then we do 7/2 , 3/2 and so on.....the rest of the code is just to chain together all these 0's and 1's tested.
                          hope i didn't miss anything...

                          Comment

                          • Motoma
                            Recognized Expert Specialist
                            • Jan 2007
                            • 3236

                            #14
                            Originally posted by bvdet
                            I don't think so, but I made this up:[code=Python]def ConvDecToBaseVa r(num, base):
                            if base > 10 or base < 2:
                            raise ValueError, 'The base number must be between 2 and 10.'
                            if num == 0: return 0
                            ans = ''
                            while num != 0:
                            num, rem = divmod(num, base)
                            ans = str(rem)+ans
                            return int(ans)

                            '''
                            >>> ConvDecToBaseVa r(3000,2)
                            101110111000L
                            >>>
                            '''[/code]

                            Gotta love reusable code, eh?

                            Comment

                            • bvdet
                              Recognized Expert Specialist
                              • Oct 2006
                              • 2851

                              #15
                              Originally posted by Motoma
                              Gotta love reusable code, eh?
                              Yes. Here's some more recycling - [code=Python]def ConvDecToBaseVa r3(num, base):
                              if base > 16 or base < 2:
                              raise ValueError, 'The base number must be between 2 and 16.'
                              dd = dict(zip(range( 16), [hex(i).split('x ')[1] for i in range(16)]))
                              if num == 0: return ''
                              num, rem = divmod(num, base)
                              return ConvDecToBaseVa r3(num, base)+dd[rem][/code]
                              Code:
                              >>> ConvDecToBaseVar3(123456789, 16)
                              '75bcd15'
                              >>> ConvDecToBaseVar3(2**200, 16)
                              '100000000000000000000000000000000000000000000000000'
                              >>> ConvDecToBaseVar3(2**200, 7)
                              '141246066533632643213232344050606053061443446006544361632102630555343054'
                              >>>
                              It's not suitable for very long numbers due to the recursion limit.

                              Comment

                              Working...