[python] 바이트 문자열을 정수로 변환하는 방법은 무엇입니까?
파이썬에서 바이트 문자열을 int로 어떻게 변환 할 수 있습니까?
이렇게 말하십시오 : 'y\xcc\xa6\xbb'
나는 영리하고 어리석은 방법을 생각해 냈습니다.
sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))
나는 이것을 더 간단하게하는 내장 또는 표준 라이브러리에 무언가가 있어야한다는 것을 알고있다 …
이것은 int (xxx, 16)를 사용할 수있는 16 진수 문자열을 변환하는 것과 다르지만 대신 실제 바이트 값의 문자열을 변환하려고합니다.
최신 정보:
나는 다른 모듈을 가져올 필요가 없기 때문에 James의 대답이 조금 나아졌지 만 Greg의 방법이 더 빠릅니다.
>>> from timeit import Timer
>>> Timer('struct.unpack("<L", "y\xcc\xa6\xbb")[0]', 'import struct').timeit()
0.36242198944091797
>>> Timer("int('y\xcc\xa6\xbb'.encode('hex'), 16)").timeit()
1.1432669162750244
내 해키 방법 :
>>> Timer("sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))").timeit()
2.8819329738616943
추가 업데이트 :
누군가 다른 모듈을 가져 오는 데 어떤 문제가 있는지 의견을 물었습니다. 글쎄, 모듈을 임포트하는 것이 반드시 싼 것은 아닙니다.
>>> Timer("""import struct\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""").timeit()
0.98822188377380371
모듈을 가져 오는 비용을 포함 시키면이 방법이 갖는 거의 모든 이점이 무시됩니다. 여기에는 전체 벤치 마크 실행시 한 번만 가져 오는 비용이 포함된다고 생각합니다. 매번 다시로드 할 때 어떤 일이 발생하는지보십시오.
>>> Timer("""reload(struct)\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""", 'import struct').timeit()
68.474128007888794
말할 필요도없이, 한 번의 가져 오기 마다이 방법을 많이 실행하면 이보다 비례 적으로 덜 문제가됩니다. CPU가 아닌 i / o 비용 일 수 있으므로 특정 머신의 용량 및로드 특성에 따라 달라질 수 있습니다.
답변
struct 모듈을 사용하여 이를 수행 할 수도 있습니다 .
>>> struct.unpack("<L", "y\xcc\xa6\xbb")[0]
3148270713L
답변
Python 3.2 이상에서
>>> int.from_bytes(b'y\xcc\xa6\xbb', byteorder='big')
2043455163
또는
>>> int.from_bytes(b'y\xcc\xa6\xbb', byteorder='little')
3148270713
바이트 문자열 의 엔디안 에 따라 .
이것은 또한 임의의 길이의 바이트 문자열-정수 및을 지정하여 2의 보수 부호있는 정수에 대해서도 작동합니다 signed=True
. 에 대한 문서를from_bytes
참조하십시오 .
답변
Greg가 말했듯이 이진 값을 처리하는 경우 struct를 사용할 수 있지만 “16 진수”만 있고 바이트 형식이면 다음과 같이 변환 할 수 있습니다.
s = 'y\xcc\xa6\xbb'
num = int(s.encode('hex'), 16)
… 이것은 다음과 같습니다 :
num = struct.unpack(">L", s)[0]
… 모든 바이트에서 작동한다는 점을 제외하고.
답변
다음 함수를 사용하여 int, hex 및 bytes 사이의 데이터를 변환합니다.
def bytes2int(str):
return int(str.encode('hex'), 16)
def bytes2hex(str):
return '0x'+str.encode('hex')
def int2bytes(i):
h = int2hex(i)
return hex2bytes(h)
def int2hex(i):
return hex(i)
def hex2int(h):
if len(h) > 1 and h[0:2] == '0x':
h = h[2:]
if len(h) % 2:
h = "0" + h
return int(h, 16)
def hex2bytes(h):
if len(h) > 1 and h[0:2] == '0x':
h = h[2:]
if len(h) % 2:
h = "0" + h
return h.decode('hex')
출처 : http://opentechnotes.blogspot.com.au/2014/04/convert-values-to-from-integer-hex.html
답변
import array
integerValue = array.array("I", 'y\xcc\xa6\xbb')[0]
경고 : 위의 내용은 플랫폼에 따라 다릅니다. “I”지정자와 문자열-> int 변환의 엔디안은 모두 특정 Python 구현에 따라 다릅니다. 그러나 한 번에 많은 정수 / 문자열을 변환하려면 배열 모듈이 빠르게 수행합니다.
답변
Python 2.x에서는 형식 지정자를 사용할 수 있습니다 <B
부호없는 <b
바이트와 struct.unpack
/를 부호있는 바이트에 를struct.pack
.
예 :
허락하다 x
='\xff\x10\x11'
data_ints = struct.unpack('<' + 'B'*len(x), x) # [255, 16, 17]
과:
data_bytes = struct.pack('<' + 'B'*len(data_ints), *data_ints) # '\xff\x10\x11'
그 *
필요합니다!
보다 형식 지정자 목록은 https://docs.python.org/2/library/struct.html#format-characters 를 참조하십시오 .
답변
>>> reduce(lambda s, x: s*256 + x, bytearray("y\xcc\xa6\xbb"))
2043455163
테스트 1 : 역 :
>>> hex(2043455163)
'0x79cca6bb'
테스트 2 : 바이트 수> 8
>>> reduce(lambda s, x: s*256 + x, bytearray("AAAAAAAAAAAAAAA"))
338822822454978555838225329091068225L
테스트 3 : 하나씩 증가
>>> reduce(lambda s, x: s*256 + x, bytearray("AAAAAAAAAAAAAAB"))
338822822454978555838225329091068226L
테스트 4 : 1 바이트 추가, ‘A’:
>>> reduce(lambda s, x: s*256 + x, bytearray("AAAAAAAAAAAAAABA"))
86738642548474510294585684247313465921L
테스트 5 : 256으로 나누기 :
>>> reduce(lambda s, x: s*256 + x, bytearray("AAAAAAAAAAAAAABA"))/256
338822822454978555838225329091068226L
결과는 예상대로 시험 4의 결과와 같습니다.