简体   繁体   English

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

[英]Print a string as hexadecimal bytes

I have this string: Hello, World!我有这个字符串: Hello, World! and I want to print it using Python as '48:65:6c:6c:6f:2c:20:57:6f:72:6c:64:21'.我想使用 Python 将其打印为“48:65:6c:6c:6f:2c:20:57:6f:72:6c:64:21”。

hex() works only for integers. hex()仅适用于整数。

How can it be done?如何做呢?

You can transform your string to an integer generator.您可以将字符串转换为整数生成器。 Apply hexadecimal formatting for each element and intercalate with a separator:为每个元素应用十六进制格式并插入分隔符:

>>> s = "Hello, World!"
>>> ":".join("{:02x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:2c:20:57:6f:72:6c:64:21
':'.join(x.encode('hex') for x in 'Hello, World!')

For Python 2.x:对于 Python 2.x:

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

The code above will not work with Python 3.x .上面的代码不适用于 Python 3.x For 3.x, the code below will work:对于 3.x,下面的代码将起作用:

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

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对于 Python 2.7

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

For Python 3.7 (not tested on all releases of 3)对于 Python 3.7(未在 3 的所有版本上测试)

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

Some complements to Fedor Gogolev's answer :Fedor Gogolev 的回答的一些补充:

First, if the string contains characters whose ASCII code is below 10, they will not be displayed as required.首先,如果字符串中包含ASCII 码小于 10 的字符,则不会按要求显示。 In that case, the correct format should be {:02x} :在这种情况下,正确的格式应该是{: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: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: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:其次,如果您的“字符串”实际上是一个“字节字符串”——并且由于 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:21:21'

Please note there is no need for conversion in the above code as a bytes object is defined as "an immutable sequence of integers in the range 0 <= x < 256" .请注意,在上面的代码中不需要转换,因为字节对象被定义“范围 0 <= x < 256 内的不可变整数序列”

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).接受的答案仅在您使用字节(主要是 ascii 字符)时才有效。 But if you use unicode, eg:但是如果你使用unicode,例如:

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):如果您的终端不接受这些字符,您可以从 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}"
)

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.一个贫穷的/出乎意料的结果-这些结合起来,使我们在Unicode中看到字形,从Unicode协会的代码点-代表语言在世界各地。 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.为了允许其他来源使用此数据,我们通常需要转换为 UTF-8 编码,例如,将此字符串以字节为单位保存到磁盘或发布到 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:所以我们需要这种编码来将代码点转换为 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'

Or perhaps more elegantly, using the new f-strings (only available in Python 3):或者更优雅地,使用新的 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'

In Python 2, pass c to ord first, ie ord(c) - more examples:在 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'

You can use hexdump 's:您可以使用hexdump的:

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

(append .lower() if you require lower-case). (如果需要小写,请附加.lower() )。 This works for both Python 2 and 3.这适用于 Python 2 和 3。

Using map and lambda function can produce a list of hex values, which can be printed (or used for other purposes)使用 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']

A bit more general for those who don't care about Python 3 or colons:对于那些不关心 Python 3 或冒号的人来说,更通用一点:

from codecs import encode

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

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

This can be done in the 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 hexadecimal as follows:其输出将以十六进制表示,如下所示:

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

For something that offers more performance than ''.format() , you can use this:对于提供比''.format()更高性能的东西,你可以使用这个:

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

I am sorry this couldn't look nicer.我很抱歉这不能看起来更好。

It would be nice if one could simply do '%02x'%v , but that only takes int...如果可以简单地执行'%02x'%v会很好,但这只需要 int ...

But you'll be stuck with byte-strings b'' without the logic to select ord(v) .但是,如果没有选择ord(v)的逻辑,您将被字节字符串b''困住。

In Python 3: 在Python 3中:

":".join(c.encode().hex() for c in "Hello world !!")
# 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21

This is similar to @Aesthete's answer. 这类似于@Esthete的回答。

I have this string: Hello world !!我有这个字符串: 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 .我想使用Python作为48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21打印它。

hex() works only for integers. hex()仅适用于整数。

How can it be done?怎么做到呢?

Just for convenience, very simple.只是为了方便,很简单。

def hexlify_byteString(byteString, delim="%"):
    ''' Very simple way to hexlify a byte string 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:2C:20:57:6F:72:6C:64:21'

With f-string:使用 f 字符串:

"".join(f"{ord(c):x}" for c in "Hello")

Use any delimiter:使用任何分隔符:

>>> "⚡".join(f"{ord(c):x}" for c in "Hello")
'48⚡65⚡6c⚡6c⚡6f'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM