Làm thế nào tôi có thể chuyển đổi một chuỗi byte thành một int trong python?
Nói như thế này: 'y\xcc\xa6\xbb'
Tôi đã nghĩ ra một cách thông minh / ngu ngốc để làm điều đó:
sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))
Tôi biết rằng phải có một cái gì đó dựng sẵn hoặc trong thư viện tiêu chuẩn thực hiện việc này đơn giản hơn ...
Điều này khác với việc chuyển đổi một chuỗi các chữ số hex mà bạn có thể sử dụng int (xxx, 16), nhưng thay vào đó tôi muốn chuyển đổi một chuỗi các giá trị byte thực tế.
CẬP NHẬT:
Tôi giống như câu trả lời của James tốt hơn một chút vì nó không yêu cầu nhập mô-đun khác, nhưng phương pháp của Greg nhanh hơn:
>>> 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
Phương pháp hack của tôi:
>>> Timer("sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))").timeit()
2.8819329738616943
CẬP NHẬT THÊM:
Có người hỏi ý kiến về vấn đề nhập mô-đun khác. Chà, nhập một mô-đun không nhất thiết phải rẻ, hãy xem:
>>> Timer("""import struct\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""").timeit()
0.98822188377380371
Bao gồm chi phí nhập khẩu mô-đun phủ nhận gần như tất cả các lợi thế mà phương pháp này có. Tôi tin rằng điều này sẽ chỉ bao gồm chi phí nhập nó một lần cho toàn bộ hoạt động chuẩn; hãy nhìn những gì xảy ra khi tôi buộc nó tải lại mỗi lần:
>>> Timer("""reload(struct)\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""", 'import struct').timeit()
68.474128007888794
Không cần phải nói, nếu bạn đang thực hiện rất nhiều lần thực hiện phương thức này cho mỗi lần nhập thì điều này sẽ trở thành một vấn đề tương đối ít hơn. Nó cũng có thể là chi phí thay vì cpu vì vậy nó có thể phụ thuộc vào công suất và đặc tính tải của máy cụ thể.
int.from_bytes
) được thực hiện struct.unpack
trên máy tính của tôi. Bên cạnh là imo dễ đọc hơn.