问题:将字符串打印为十六进制字节?

我有这个字符串:Hello world !!我想使用Python作为打印它48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21

hex() 仅适用于整数。

如何做呢?

I have this string: Hello world !! and I want to print it using Python as 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21.

hex() works only for integers.

How can it be done?


回答 0

您可以将字符串转换为int生成器,对每个元素应用十六进制格式,并使用分隔符插入:

>>> s = "Hello world !!"
>>> ":".join("{:02x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21

Your can transform your string to a int generator, apply hex formatting for each element and intercalate with separator:

>>> s = "Hello world !!"
>>> ":".join("{:02x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21

回答 1

':'.join(x.encode('hex') for x in 'Hello World!')
':'.join(x.encode('hex') for x in 'Hello World!')

回答 2

对于Python 2.x:

':'.join(x.encode('hex') for x in 'Hello World!')

上面的代码不适用于Python 3.x,对于3.x,下面的代码将起作用:

':'.join(hex(ord(x))[2:] for x in 'Hello World!')

For Python 2.x:

':'.join(x.encode('hex') for x in 'Hello World!')

The code above will not work with Python 3.x, for 3.x, the code below will work:

':'.join(hex(ord(x))[2:] for x in 'Hello World!')

回答 3

两行中的另一个答案可能使某些人更容易阅读,并且有助于调试字符串中的换行符或其他奇数字符:

对于Python 2.7

for character in string:
    print character, character.encode('hex')

对于Python 3.7(未在3的所有版本上进行测试)

for character in string:
    print(character, character.encode('utf-8').hex())

Another answer in two lines that some might find easier to read, and helps with debugging line breaks or other odd characters in a string:

For Python 2.7

for character in string:
    print character, character.encode('hex')

For Python 3.7 (not tested on all releases of 3)

for character in string:
    print(character, character.encode('utf-8').hex())

回答 4

Fedor Gogolev答案的一些补充:

首先,如果字符串包含“ ASCII码”低于10的字符,则不会按要求显示它们。在这种情况下,正确的格式应为{:02x}

>>> s = "Hello unicode \u0005 !!"
>>> ":".join("{0:x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:75:6e:69:63:6f:64:65:20:5:20:21:21'
                                           ^

>>> ":".join("{:02x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:75:6e:69:63:6f:64:65:20:05:20:21:21'
                                           ^^

其次,如果您的“字符串”实际上是“字节字符串”-并且由于区别在Python 3中很重要-您可能更喜欢以下内容:

>>> s = b"Hello bytes \x05 !!"
>>> ":".join("{:02x}".format(c) for c in s)
'48:65:6c:6c:6f:20:62:79:74:65:73:20:05:20:21:21'

请注意,由于字节对象被定义“范围在0 <= x <256之间的不可变整数序列”,因此不需要在上面的代码中进行转换。

Some complements to Fedor Gogolev answer:

First, if the string contains characters whose ‘ASCII code’ is below 10, they will not be displayed as required. In that case, the correct format should be {:02x}:

>>> s = "Hello unicode \u0005 !!"
>>> ":".join("{0:x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:75:6e:69:63:6f:64:65:20:5:20:21:21'
                                           ^

>>> ":".join("{:02x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:75:6e:69:63:6f:64:65:20:05:20:21:21'
                                           ^^

Second, if your “string” is in reality a “byte string” — and since the difference matters in Python 3 — you might prefer the following:

>>> s = b"Hello bytes \x05 !!"
>>> ":".join("{:02x}".format(c) for c in s)
'48:65:6c:6c:6f:20:62:79:74:65:73:20:05:20:21:21'

Please note there is no need for conversion in the above code as a bytes objects is defined as “an immutable sequence of integers in the range 0 <= x < 256”.


回答 5

将字符串打印为十六进制字节?

接受的答案给出:

s = "Hello world !!"
":".join("{:02x}".format(ord(c)) for c in s)

返回:

'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21'

只要您使用字节(主要是ascii字符),可接受的答案就起作用。但是,如果您使用unicode,例如:

a_string = u"Привет мир!!" # "Prevyet mir", or "Hello World" in Russian.

您需要以某种方式转换为字节。

如果您的终端不接受这些字符,则可以从UTF-8解码或使用名称(以便可以与我一起粘贴并运行代码):

a_string = (
    "\N{CYRILLIC CAPITAL LETTER PE}"
    "\N{CYRILLIC SMALL LETTER ER}"
    "\N{CYRILLIC SMALL LETTER I}"
    "\N{CYRILLIC SMALL LETTER VE}"
    "\N{CYRILLIC SMALL LETTER IE}"
    "\N{CYRILLIC SMALL LETTER TE}"
    "\N{SPACE}"
    "\N{CYRILLIC SMALL LETTER EM}"
    "\N{CYRILLIC SMALL LETTER I}"
    "\N{CYRILLIC SMALL LETTER ER}"
    "\N{EXCLAMATION MARK}"
    "\N{EXCLAMATION MARK}"
)

因此,我们看到:

":".join("{:02x}".format(ord(c)) for c in a_string)

退货

'41f:440:438:432:435:442:20:43c:438:440:21:21'

不良/意外的结果-这些代码点结合在一起,构成了来自Unicode联盟的Unicode 字形,代表了全世界的语言。但是,这并不是我们实际存储此信息的方式,因此可以由其他来源对其进行解释。

为了允许另一个源使用此数据,我们通常需要转换为UTF-8编码,例如,将该字符串以字节为单位保存到磁盘或发布为html。因此,我们需要进行编码以将代码点转换为UTF-8 的代码单元 -在Python 3中ord是不需要的,因为bytes整数是可迭代的:

>>> ":".join("{:02x}".format(c) for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'

或者,也许更优雅地使用新的f字符串(仅在Python 3中可用):

>>> ":".join(f'{c:02x}' for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'

在Python 2中,请c转到ord第一个,即ord(c)-更多示例:

>>> ":".join("{:02x}".format(ord(c)) for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'
>>> ":".join(format(ord(c), '02x') for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'

Print a string as hex bytes?

The accepted answer gives:

s = "Hello world !!"
":".join("{:02x}".format(ord(c)) for c in s)

returns:

'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21'

The accepted answer works only so long as you use bytes (mostly ascii characters). But if you use unicode, e.g.:

a_string = u"Привет мир!!" # "Prevyet mir", or "Hello World" in Russian.

You need to convert to bytes somehow.

If your terminal doesn’t accept these characters, you can decode from UTF-8 or use the names (so you can paste and run the code along with me):

a_string = (
    "\N{CYRILLIC CAPITAL LETTER PE}"
    "\N{CYRILLIC SMALL LETTER ER}"
    "\N{CYRILLIC SMALL LETTER I}"
    "\N{CYRILLIC SMALL LETTER VE}"
    "\N{CYRILLIC SMALL LETTER IE}"
    "\N{CYRILLIC SMALL LETTER TE}"
    "\N{SPACE}"
    "\N{CYRILLIC SMALL LETTER EM}"
    "\N{CYRILLIC SMALL LETTER I}"
    "\N{CYRILLIC SMALL LETTER ER}"
    "\N{EXCLAMATION MARK}"
    "\N{EXCLAMATION MARK}"
)

So we see that:

":".join("{:02x}".format(ord(c)) for c in a_string)

returns

'41f:440:438:432:435:442:20:43c:438:440:21:21'

a poor/unexpected result – these are the code points that combine to make the graphemes we see in Unicode, from the Unicode Consortium – representing languages all over the world. This is not how we actually store this information so it can be interpreted by other sources, though.

To allow another source to use this data, we would usually need to convert to UTF-8 encoding, for example, to save this string in bytes to disk or to publish to html. So we need that encoding to convert the code points to the code units of UTF-8 – in Python 3, ord is not needed because bytes are iterables of integers:

>>> ":".join("{:02x}".format(c) for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'

Or perhaps more elegantly, using the new f-strings (only available in Python 3):

>>> ":".join(f'{c:02x}' for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'

In Python 2, pass c to ord first, i.e. ord(c) – more examples:

>>> ":".join("{:02x}".format(ord(c)) for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'
>>> ":".join(format(ord(c), '02x') for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'

回答 6

您可以使用hexdump

import hexdump
hexdump.dump("Hello World", sep=":")

.lower()如果需要小写,请附加)。这适用于Python 2和3。

You can use hexdump‘s

import hexdump
hexdump.dump("Hello World", sep=":")

(append .lower() if you require lower-case). This works for both Python 2 & 3.


回答 7

使用map和lambda函数可以生成一个十六进制值列表,可以将其打印(或用于其他目的)

>>> s = 'Hello 1 2 3 \x01\x02\x03 :)'

>>> map(lambda c: hex(ord(c)), s)
['0x48', '0x65', '0x6c', '0x6c', '0x6f', '0x20', '0x31', '0x20', '0x32', '0x20', '0x33', '0x20', '0x1', '0x2', '0x3', '0x20', '0x3a', '0x29']

Using map and lambda function can produce a list of hex values, which can be printed (or used for other purposes)

>>> s = 'Hello 1 2 3 \x01\x02\x03 :)'

>>> map(lambda c: hex(ord(c)), s)
['0x48', '0x65', '0x6c', '0x6c', '0x6f', '0x20', '0x31', '0x20', '0x32', '0x20', '0x33', '0x20', '0x1', '0x2', '0x3', '0x20', '0x3a', '0x29']

回答 8

这可以通过以下方式完成:

from __future__ import print_function
str = "Hello World !!"
for char in str:
    mm = int(char.encode('hex'), 16)
    print(hex(mm), sep=':', end=' ' )

此输出将为十六进制,如下所示:

0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x20 0x21 0x21

This can be done in following ways:

from __future__ import print_function
str = "Hello World !!"
for char in str:
    mm = int(char.encode('hex'), 16)
    print(hex(mm), sep=':', end=' ' )

The output of this will be in hex as follows:

0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x20 0x21 0x21


回答 9

对于那些不关心Python3或冒号的人来说,更通用一些:

from codecs import encode

data = open('/dev/urandom', 'rb').read(20)
print(encode(data, 'hex'))      # data

print(encode(b"hello", 'hex'))  # string

A bit more general for those who don’t care about Python3 or colons:

from codecs import encode

data = open('/dev/urandom', 'rb').read(20)
print(encode(data, 'hex'))      # data

print(encode(b"hello", 'hex'))  # string

回答 10

base64.b16encodepython2中使用(内置)

>>> s = 'Hello world !!'
>>> h = base64.b16encode(s)
>>> ':'.join([h[i:i+2] for i in xrange(0, len(h), 2)]
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'

Using base64.b16encode in python2 (its built-in)

>>> s = 'Hello world !!'
>>> h = base64.b16encode(s)
>>> ':'.join([h[i:i+2] for i in xrange(0, len(h), 2)]
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'

回答 11

为了方便起见,非常简单。

def hexlify_byteString(byteString, delim="%"):
    ''' very simple way to hexlify a bytestring using delimiters '''
    retval = ""
    for intval in byteString:
        retval += ( '0123456789ABCDEF'[int(intval / 16)])
        retval += ( '0123456789ABCDEF'[int(intval % 16)])
        retval += delim
    return( retval[:-1])

hexlify_byteString(b'Hello World!', ":")
# Out[439]: '48:65:6C:6C:6F:20:57:6F:72:6C:64:21'

Just for convenience, very simple.

def hexlify_byteString(byteString, delim="%"):
    ''' very simple way to hexlify a bytestring using delimiters '''
    retval = ""
    for intval in byteString:
        retval += ( '0123456789ABCDEF'[int(intval / 16)])
        retval += ( '0123456789ABCDEF'[int(intval % 16)])
        retval += delim
    return( retval[:-1])

hexlify_byteString(b'Hello World!', ":")
# Out[439]: '48:65:6C:6C:6F:20:57:6F:72:6C:64:21'

回答 12

对于性能比更高的东西''.format(),您可以使用以下代码:

>>> ':'.join( '%02x'%(v if type(v) is int else ord(v)) for v in 'Hello World !!' )
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'
>>> 
>>> ':'.join( '%02x'%(v if type(v) is int else ord(v)) for v in b'Hello World !!' )
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'
>>> 

抱歉,
如果一个人可以简单地做到'%02x'%v这一点,那就再好不过了,但这只需要int …,
但是您会被字节字符串所困扰,b''而没有选择逻辑ord(v)

for something that offers more performance than ''.format(), you can use this:

>>> ':'.join( '%02x'%(v if type(v) is int else ord(v)) for v in 'Hello World !!' )
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'
>>> 
>>> ':'.join( '%02x'%(v if type(v) is int else ord(v)) for v in b'Hello World !!' )
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'
>>> 

sorry this couldn’t look nicer
would be nice if one could simply do '%02x'%v, but that only takes int…
but you’ll be stuck with byte-strings b'' without the logic to select ord(v).


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。