바이트 문자열을 int로 변환하는 방법은 무엇입니까?
파이썬에서 바이트 문자열을 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 비용일 수 있으므로 특정 시스템의 용량 및 로드 특성에 따라 달라질 수 있습니다.
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
의 문서를 참조하십시오.
구조 모듈을 사용하여 다음 작업을 수행할 수도 있습니다.
>>> struct.unpack("<L", "y\xcc\xa6\xbb")[0]
3148270713L
Greg가 말했듯이, 이진수 값을 다루는 경우 구조체를 사용할 수 있지만, "16진수"이지만 바이트 형식이라면 다음과 같이 변환하고 싶을 수 있습니다.
s = 'y\xcc\xa6\xbb'
num = int(s.encode('hex'), 16)
...이것은 다음과 같습니다.
num = struct.unpack(">L", s)[0]
...바이트 수에 상관없이 작동합니다.
나는 다음 함수를 사용하여 int, hex 및 byt 사이의 데이터를 변환합니다.
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" 지정자와 string->int 변환의 엔디언은 모두 특정 Python 구현에 따라 달라집니다.그러나 한 번에 많은 정수/문자열을 변환하려는 경우 어레이 모듈이 빠르게 변환합니다.
2 Python 2.x를 할 수 .<B
없는 바이트의 경우, 서되지않바의트경우이은명경▁for.<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: 1씩 증가:
>>> 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의 결과와 같습니다.
저는 Python 2.x에서 작동할 임의의 길이 바이트 시퀀스에 대한 솔루션을 찾는 데 어려움을 겪고 있었습니다.마침내 제가 이것을 썼습니다. 문자열 변환을 수행하기 때문에 약간 구식이지만 작동합니다.
Python 2.x용 함수, 임의 길이
def signedbytes(data):
"""Convert a bytearray into an integer, considering the first bit as
sign. The data must be big-endian."""
negative = data[0] & 0x80 > 0
if negative:
inverted = bytearray(~d % 256 for d in data)
return -signedbytes(inverted) - 1
encoded = str(data).encode('hex')
return int(encoded, 16)
이 기능에는 두 가지 요구 사항이 있습니다.
력
data
다음이 필요합니다.bytearray
은 다음과 수 .s = 'y\xcc\xa6\xbb' n = signedbytes(s)
데이터는 빅 엔디안이어야 합니다.리틀 엔디안 값이 있는 경우 먼저 값을 반대로 설정해야 합니다.
n = signedbytes(s[::-1])
물론 임의의 길이가 필요한 경우에만 사용해야 합니다. 더 인 방법 ▁(방(법:▁with▁otherwise인)을 고수합니다.struct
).
버전 >=3.2인 경우 int.from_bytes가 가장 좋은 솔루션입니다.struct.unpack 솔루션에는 문자열이 필요하므로 바이트 배열에 적용되지 않습니다.다음은 또 다른 솔루션입니다.
def bytes2int( tb, order='big'):
if order == 'big': seq=[0,1,2,3]
elif order == 'little': seq=[3,2,1,0]
i = 0
for j in seq: i = (i<<8)+tb[j]
return i
hex(bytes2int([0x87, 0x65, 0x43, 0x21]))는 '0x87654321'을 반환합니다.
크고 작은 엔디언을 처리하며 8바이트에 대해 쉽게 수정할 수 있습니다.
처럼 에서언바같와사이용한을 사용합니다.unpack
구조의 기능은 좋은 방법입니다.독자적인 기능을 구현하려면 다음과 같은 다른 솔루션이 방법은 다음과 같습니다.
def bytes_to_int(bytes):
result = 0
for b in bytes:
result = result * 256 + int(b)
return result
python 3에서 당신은 바이트 문자열을 쉽게 정수 (0..255)
>>> list(b'y\xcc\xa6\xbb')
[121, 204, 166, 187]
제가 한동안 사용해온 array.array를 활용한 꽤 빠른 방법:
미리 정의된 변수:
offset = 0
size = 4
big = True # endian
arr = array('B')
arr.fromstring("\x00\x00\xff\x00") # 5 bytes (encoding issues) [0, 0, 195, 191, 0]
int: (읽음)
val = 0
for v in arr[offset:offset+size][::pow(-1,not big)]: val = (val<<8)|v
int에서: (쓰기)
val = 16384
arr[offset:offset+size] = \
array('B',((val>>(i<<3))&255 for i in range(size)))[::pow(-1,not big)]
하지만 이것들이 더 빠를 수도 있습니다.
수치에 읽기에서 안정적인 테스트 2가 일부수의아경다, 성테스트능같가은 (우나다 2.3.0)와 하여 보여줍니다.reduce()
:
========================= byte array to int.py =========================
5000 iterations; threshold of min + 5000ns:
______________________________________code___|_______min______|_______max______|_______avg______|_efficiency
⣿⠀⠀⠀⠀⡇⢀⡀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⡀⠀⢰⠀⠀⠀⢰⠀⠀⠀⢸⠀⠀⢀⡇⠀⢀⠀⠀⠀⠀⢠⠀⠀⠀⠀⢰⠀⠀⠀⢸⡀⠀⠀⠀⢸⠀⡇⠀⠀⢠⠀⢰⠀⢸⠀
⣿⣦⣴⣰⣦⣿⣾⣧⣤⣷⣦⣤⣶⣾⣿⣦⣼⣶⣷⣶⣸⣴⣤⣀⣾⣾⣄⣤⣾⡆⣾⣿⣿⣶⣾⣾⣶⣿⣤⣾⣤⣤⣴⣼⣾⣼⣴⣤⣼⣷⣆⣴⣴⣿⣾⣷⣧⣶⣼⣴⣿⣶⣿⣶
val = 0 \nfor v in arr: val = (val<<8)|v | 5373.848ns | 850009.965ns | ~8649.64ns | 62.128%
⡇⠀⠀⢀⠀⠀⠀⡇⠀⡇⠀⠀⣠⠀⣿⠀⠀⠀⠀⡀⠀⠀⡆⠀⡆⢰⠀⠀⡆⠀⡄⠀⠀⠀⢠⢀⣼⠀⠀⡇⣠⣸⣤⡇⠀⡆⢸⠀⠀⠀⠀⢠⠀⢠⣿⠀⠀⢠⠀⠀⢸⢠⠀⡀
⣧⣶⣶⣾⣶⣷⣴⣿⣾⡇⣤⣶⣿⣸⣿⣶⣶⣶⣶⣧⣷⣼⣷⣷⣷⣿⣦⣴⣧⣄⣷⣠⣷⣶⣾⣸⣿⣶⣶⣷⣿⣿⣿⣷⣧⣷⣼⣦⣶⣾⣿⣾⣼⣿⣿⣶⣶⣼⣦⣼⣾⣿⣶⣷
val = reduce( shift, arr ) | 6489.921ns | 5094212.014ns | ~12040.269ns | 53.902%
이것은 원시 성능 테스트이므로 엔디안 파워플립은 제외됩니다.
그shift
루프와 하며, for 루프의 경우에는 표된기오링-은능니다-작적동합용을시시를 적용합니다.arr
당한입니다.array.array('B',[0,0,255,0])
다음으로 빠른 반복 성능을 가지고 있기 때문에dict
.
효율성은 평균 시간에 대한 정확도로 측정된다는 점도 유의해야 합니다.
최신 버전의 Python의 경우 간단한 방법은 다음과 같습니다.
int(b'hello world'.hex(), 16)
언급URL : https://stackoverflow.com/questions/444591/how-to-convert-a-string-of-bytes-into-an-int
'programing' 카테고리의 다른 글
IIS7에서 eTag 헤더를 제거하려면 어떻게 해야 합니까? (0) | 2023.07.03 |
---|---|
NumericTextField를 사용할 때 "프롭을 직접 변환하지 않음"이 표시되는 이유는 무엇입니까? (0) | 2023.07.03 |
UI 이미지:크기 조정 후 자르기 (0) | 2023.07.03 |
오늘 날짜와 결과를 비교하시겠습니까? (0) | 2023.07.03 |
여기에 "오픈 깃배시"를 추가하는 방법.윈도우 탐색기의 상황에 맞는 메뉴? (0) | 2023.07.03 |