10

Is there an easy way to get some str/unicode object represented as a big binary number (or an hex one)?

I've been reading some answers to related questions but none of them works for my scenario.

I tried using the struct module from the STL but it didn't work as expected. Chars, like in binary files are displayed as, well chars.

Am I trying something impossible?

Example:

def strbin(inp):
    # sorcery!
    return out

>> print strbin("hello")
# Any of these is cool (outputs are random keystrokes)
0b1001010101010000111001110001...
0xad9f...
toqueteos
  • 771
  • 1
  • 6
  • 14
  • Are you trying to get an integer or a string of the hex/binary representation? In your example you have integers given as binary and hex literals. – Peter Graham Jul 18 '11 at 02:20
  • @Peter, in most of the use scenarios I'm thinking of I would say an integer. This is just for some silly compression algorithm I thought some days ago, just for fun. – toqueteos Jul 18 '11 at 02:53
  • related: [Convert binary to ASCII and vice versa](http://stackoverflow.com/q/7396849/4279) – jfs Nov 18 '15 at 13:31

5 Answers5

19

You could try bitarray:

>>> import bitarray
>>> b = bitarray.bitarray()
>>> b.fromstring('a')
>>> b
bitarray('01100001')
>>> b.to01()
'01100001'
>>> b.fromstring('pples')
>>> b.tostring()
'apples'
>>> b.to01()
'011000010111000001110000011011000110010101110011'
senderle
  • 145,869
  • 36
  • 209
  • 233
  • 1
    I can't give you and upvote senderle (still 4 reputation left for that) but your answer is what I was looking for. Checking this as accepted answer :) Thank you so much. – toqueteos Jul 18 '11 at 02:15
  • 1
    I'll also mention [`bitstring`](http://pypi.python.org/pypi/bitstring/2.2.0), which I think is a tad bit more versatile, but it's pure Python, so it's slower. – senderle Jul 18 '11 at 02:21
  • There's no STL library that could this without some sorcery right? Just curious. **Edit:** Oh and you got the upboat. – toqueteos Jul 18 '11 at 02:36
  • @ratnushock, well, once you _have_ an int, you could call `bin` on it. But that doesn't pad the byte, so it doesn't concatenate well. (`hex` doesn't pad either; `hex(5)` returns `'0x5'`.) [JBernardo's answer](http://stackoverflow.com/questions/6728077/convert-python-str-unicode-object-to-binary-hex-blob/6728196#6728196) gets the padding right and is as good as anything I can think of from the standard libraries. – senderle Jul 18 '11 at 02:46
7

Quite simple and don't require modules from pypi:

def strbin(s):
    return ''.join(format(ord(i),'0>8b') for i in s)

You'll need Python 2.6+ to use that.

JBernardo
  • 32,262
  • 10
  • 90
  • 115
  • Well I'm pretty sure that @senderle 's answer is gonna be faster just because it's a C extension but hey STL solutions are also great. Thanks for your answer! – toqueteos Jul 18 '11 at 02:42
  • 4
    Probably you don't need it to be that fast. Otherwise why would you write in Python at all? Quoting the Zen: Simple is better than complex – JBernardo Jul 18 '11 at 02:56
1

This is basically Ravi's answer but with a tiny bugfix, so all credit to him, but the consensus among reviewers was that this was too big of a change to just do an edit and should be a separate answer instead... No idea why.

def strhex(str):
    h=""
    for x in str:
        h=h+("0" + (hex(ord(x)))[2:])[-2:]
    return "0x"+h

The difference is that in line 4, you have to check if the character is less than 0x10 and in that case prepend a zero, otherwise e.g. 0x1101 becomes 0x111.

Community
  • 1
  • 1
FrederikVds
  • 551
  • 4
  • 11
1
def strhex(str):
    h=""
    for x in str:
        h=h+(hex(ord(x)))[2:]
    return "0x"+h
Ravi
  • 3,718
  • 7
  • 39
  • 57
  • This returns the ASCII number not the binary repr but it works in a similar way so.. Thanks for your answer! – toqueteos Jul 18 '11 at 02:35
  • Don't the above answers also return ASCII? If you need an int, you could add int(h,16) at the end. – Ravi Jul 18 '11 at 03:12
1

A slice from a larger pretty print function I wrote that prints the ascii code in hex. Just a more Pythonic version of the previous answer's function. Also, it works properly for characters with single digit ascii codes.

def strhex(string, start = '0x'):
    return start + ''.join(('{:x}'.format(ord(char))).zfill(2) for char in string)
agf
  • 171,228
  • 44
  • 289
  • 238