Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert little endian string to integer

Tags:

python

numpy

wav

I have read samples out of a wave file using the wave module, but it gives the samples as a string, it's out of wave so it's little endian (for example, \x00).

What is the easiest way to convert this into a python integer, or a numpy.int16 type? (It will eventually become a numpy.int16, so going directly there is fine).

Code needs to work on little endian and big endian processors.

like image 921
Jeffrey Aylesworth Avatar asked Nov 08 '09 21:11

Jeffrey Aylesworth


People also ask

How does Little Endian store integers?

On little endian platforms, the value 1 is stored in one byte as 01 (the same as big endian), in two bytes as 01 00, and in four bytes as 01 00 00 00. If an integer is negative, the "two's complement" representation is used. The high-order bit of the most significant byte of the integer will be set on.

What is little endian integer?

Specifically, little-endian is when the least significant bytes are stored before the more significant bytes, and big-endian is when the most significant bytes are stored before the less significant bytes. When we write a number (in hex), i.e. 0x12345678 , we write it with the most significant byte first (the 12 part).

What is endian swap?

The SWAP_ENDIAN function reverses the byte ordering of arbitrary scalars, arrays or structures. It can make “big endian” number “little endian” and vice-versa.

Can little endian vs big-endian?

Big-endian is an order in which the "big end" (most significant value in the sequence) is stored first, at the lowest storage address. Little-endian is an order in which the "little end" (least significant value in the sequence) is stored first.


2 Answers

Kevin Burke's answer to this question works great when your binary string represents a single short integer, but if your string holds binary data representing multiple integers, you will need to add an additional 'h' for each additional integer that the string represents.

For Python 2

Convert Little Endian String that represents 2 integers

import struct
iValues = struct.unpack("<hh", "\x00\x04\x01\x05")
print(iValues)

Output: (1024, 1281)

Convert Little Endian String that represents 3 integers

import struct
iValues = struct.unpack("<hhh", "\x00\x04\x01\x05\x03\x04")
print(iValues)

Output: (1024, 1281, 1027)

Obviously, it's not realistic to always guess how many "h" characters are needed, so:

import struct

# A string that holds some unknown quantity of integers in binary form
strBinary_Values = "\x00\x04\x01\x05\x03\x04"

# Calculate the number of integers that are represented by binary string data
iQty_of_Values = len(strBinary_Values)/2

# Produce the string of required "h" values
h = "h" * int(iQty_of_Values)

iValues = struct.unpack("<"+h, strBinary_Values)
print(iValues)

Output: (1024, 1281, 1027)

For Python 3

import struct

# A string that holds some unknown quantity of integers in binary form
strBinary_Values = "\x00\x04\x01\x05\x03\x04"

# Calculate the number of integers that are represented by binary string data
iQty_of_Values = len(strBinary_Values)/2

# Produce the string of required "h" values
h = "h" * int(iQty_of_Values)

iValues = struct.unpack("<"+h, bytes(strBinary_Values, "utf8"))
print(iValues)

Output: (1024, 1281, 1027)

like image 161
David M. Helmuth Avatar answered Sep 21 '22 02:09

David M. Helmuth


The struct module converts packed data to Python values, and vice-versa.

>>> import struct
>>> struct.unpack("<h", "\x00\x05")
(1280,)
>>> struct.unpack("<h", "\x00\x06")
(1536,)
>>> struct.unpack("<h", "\x01\x06")
(1537,)

"h" means a short int, or 16-bit int. "<" means use little-endian.

like image 23
Ned Batchelder Avatar answered Sep 22 '22 02:09

Ned Batchelder