파이썬 3에서 바이트를 16 진수 문자열로 변환하는 올바른 방법은 무엇입니까?


235

파이썬 3에서 바이트를 16 진수 문자열로 변환하는 올바른 방법은 무엇입니까?

나는 bytes.hex방법, bytes.decode코덱의 주장을 보았고 아무 소용없이 가장 놀라운 다른 기능을 시도했습니다. 나는 바이트를 16 진수로 원한다!


"사용하지 않고"? 어떤 특정 문제 나 오류가 발생합니까? 코드와 오류를 보여주십시오.
S.Lott

답변:



95

binascii모듈을 사용하십시오 :

>>> import binascii
>>> binascii.hexlify('foo'.encode('utf8'))
b'666f6f'
>>> binascii.unhexlify(_).decode('utf8')
'foo'

이 답변보기 : Python 3.1.1 문자열을 16 진수로


8
이거 좋다 마음이 흔들리는 것은 bytes.fromhex (hex_str)를 사용하여 16 진수를 바이트로 변환 할 수 있지만 bytes.tohex ()를 사용하여 바이트를 16 진수로 변환 할 수 없다는 것입니다.
nagylzs

1
나는 바이트와 16 진수의 관계가 어느 속성도 아닌 것으로 생각합니다 (from 16 진수가있는 이유에 대한 대답은 아닙니다). 단순한 감독이 아니라 논쟁의 여지가있는 것 같습니다 : bugs.python.org/issue3532#msg70950 . Q :이 작업을 수행하기 위해 bytes 객체의 tohex 메서드를 사용하면 문제가 있습니까? A : 그렇습니다. 코드를 복잡하게 만들고 데이터 변환에 대한 적절한 접근 방식 (즉, 메서드가 아닌 함수)에서 벗어나게합니다.
Mu Mind

3
이것이 실제로 질문에 대답합니까? 16 진수가 str아닌 a를 반환 합니다 bytes. OP가 답변에 만족하는 것 같지만이 답변을 확장 .decode("ascii")하여 "문자열"로 변환하는 것도 좋지 않습니다.
좋지 않습니다.

3
많은 사람들이이 질문 / 답변에 착륙하여 인쇄 방법을 찾고 있다고 생각했습니다 bytes. 당신이 경우 print(b'666f6f')당신은 얻을 b인쇄물에. 그렇다면 당신 .decode("ascii")은하지 않습니다. 실제로 bytes(아스키 문자열이 아닌 항목이> 128 인 실제 이진 파일) 이 어떻게 그것을 출력하고 싶었는지 생각하십시오.
루벤 라구나

5
@nagylzs : .hex()Python 3.5 이상 에는 메소드가 있습니다
jfs

43

파이썬에는 따옴표로 묶은 인쇄 가능 (7 비트 ASCII에 적합), base64 (영숫자에 적합), 16 진수 이스케이프 처리, gzip 및 bz2 압축과 같은 편리한 변환을 수행하는 바이트-바이트 표준 코덱 이 있습니다. Python 2에서는 다음을 수행 할 수 있습니다.

b'foo'.encode('hex')

파이썬 3에서 str.encode/ bytes.decode는 bytes <-> str 변환을위한 것입니다. 대신 파이썬 2와 파이썬 3에서 작동하는이 작업을 수행 할 수 있습니다 (역 의 경우 s / encode / decode / g ).

import codecs
codecs.getencoder('hex')(b'foo')[0]

Python 3.4부터는 덜 어색한 옵션이 있습니다.

codecs.encode(b'foo', 'hex')

이러한 기타 코덱은 자체 모듈 (base64, zlib, bz2, uu, quopri, binascii) 내에서도 액세스 할 수 있습니다. API는 일관성이 떨어지지 만 압축 코덱의 경우 더 많은 제어 기능을 제공합니다.


1
python 3.3 사용 :LookupError: unknown encoding: hex
Janus Troelsen

@JanusTroelsen : 'hex_codec' 시도하십시오 . 또는 사용 binascii.hexlify(b'foo')직접
JFS

7
import codecs
codecs.getencoder('hex_codec')(b'foo')[0]

Python 3.3에서 작동합니다 ( "hex"대신 "hex_codec").


아마도 흥미롭게도 파이썬 3.4에서 "hex"또는 "hex_codec"는 잘 작동합니다.
Stephen Paulger

6

이 메소드 binascii.hexlify()는 ASCII 16 진 문자열을 나타내는 로 변환 bytes됩니다 bytes. 즉, 입력의 각 바이트가 두 개의 ASCII 문자로 변환됩니다. 당신이 진실을 원한다면 결과 str를 얻을 수 .decode("ascii")있습니다.

나는 그것을 보여주는 스 니펫을 포함시켰다.

import binascii

with open("addressbook.bin", "rb") as f: # or any binary file like '/bin/ls'
    in_bytes = f.read()
    print(in_bytes) # b'\n\x16\n\x04'
    hex_bytes = binascii.hexlify(in_bytes) 
    print(hex_bytes) # b'0a160a04' which is twice as long as in_bytes
    hex_str = hex_bytes.decode("ascii")
    print(hex_str) # 0a160a04

육각 문자열에서 "0a160a04"받는 돌아올 수에 bytesbinascii.unhexlify("0a160a04")있는 등을 제공합니다b'\n\x16\n\x04'


3

좋아, 다음 답변은 Python 3에만 관심이 있다면 범위를 약간 벗어 났지만이 질문은 Python 버전을 지정하지 않아도 Google이 처음으로 맞은 문제이므로 Python 2 Python 3 모두에서 작동하는 방법이 있습니다. .

또한 바이트를 str유형으로 변환하는 것에 대한 질문을 해석하고 있습니다 . 즉, Python 2에서는 bytes-y, Python 3에서는 Unicode-y입니다.

내가 아는 가장 좋은 방법은 다음과 같습니다.

import six

bytes_to_hex_str = lambda b: ' '.join('%02x' % i for i in six.iterbytes(b))

Python 2에서 unicode_literals미래를 활성화하지 않았다고 가정하면 Python 2 또는 Python 3에 대해 다음 어설 션이 적용됩니다 .

assert bytes_to_hex_str(b'jkl') == '6a 6b 6c'

또는 ''.join()바이트 등의 공백을 생략하는 데 사용할 수 있습니다 .


3

%x0216 진수 값을 형식화하고 출력하는 형식 지정자 를 사용할 수 있습니다 . 예를 들면 다음과 같습니다.

>>> foo = b"tC\xfc}\x05i\x8d\x86\x05\xa5\xb4\xd3]Vd\x9cZ\x92~'6"
>>> res = ""
>>> for b in foo:
...     res += "%02x" % b
... 
>>> print(res)
7443fc7d05698d8605a5b4d35d56649c5a927e2736

나에 따르면, 그것은 모든 Python 버전에서 작동하며 가져 오기가 필요하지 않기 때문에 가장 좋은 대답입니다. 그러나 대문자로 hexa 문자열을 표시하는 것이 좋습니다res.upper()
Bruno L.


0

b '\ x61'을 97 또는 '0x61'로 변환하려면 다음을 시도하십시오.

[python3.5]
>>>from struct import *
>>>temp=unpack('B',b'\x61')[0] ## convert bytes to unsigned int
97
>>>hex(temp) ##convert int to string which is hexadecimal expression
'0x61'

참조 : https://docs.python.org/3.5/library/struct.html


어떻게 든 esp32에 도움이됩니다
Tejas Tank
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.