I'm fetching a value(2 bytes) from a register using AARDVARK python module. The value are returned in Hex format. So I convert the value to decimal.Since the register value can be negative, I need to convert to signed integer if required.
I came across the following piece of code that does this and I'm unable to fathom the logic behind it.
myValue = int(myValue,16)
if( myValue > 32768):
myValue = ((myValue+0x8000)&0xFFFF) - 0x8000
For example if myValue read from register is 32769 , the corresponding signed representation after using the above piece of code is -32767
Related
I'm trying to generate an x5t parameter for a header to make a request to Azure using a certificate to authenticate.
In the example given in the docs here: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials, it's saying that the SHA-1 hash of 84E05C1D98BCE3A5421D225B140B36E86A3D5534 should give an x5t value of hOBcHZi846VCHSJbFAs26Go9VTQ=
When I try to convert this hash using the following, I find the x5t value to be ODRFMDVDMUQ5OEJDRTNBNTQyMUQyMjVCMTQwQjM2RTg2QTNENTUzNA==
What am I doing wrong in the conversion process?
import base64
x="84E05C1D98BCE3A5421D225B140B36E86A3D5534"
x5t = base64.b64encode(x.encode()).decode()
print(x)
The given SHA-1 hash
84E05C1D98BCE3A5421D225B140B36E86A3D5534
is a long hexadecimal number. In your code you treat it as a string, (e.g. "84") but you need to interpret it as hexadecimal representation of a byte array (e.g. first byte is 0x84):
import base64
x = "84E05C1D98BCE3A5421D225B140B36E86A3D5534"
x5t = base64.b64encode(bytearray.fromhex(x))
print(x5t.decode())
The result is:
hOBcHZi846VCHSJbFAs26Go9VTQ=
Can someone please help with the following line of code and Error? I am unfamiliar with python value conversions.
The specific line that generates the error is:
value = struct.unpack("<h",chr(b)+chr(a))[0]
TypeError: a bytes-like object is required, not 'str'
The code fragment is:
if packet_code ==0x80: # raw value
row_length = yield
a = yield
b = yield
value = struct.unpack("<h",chr(b)+chr(a))[0]
The input data is:
b'\x04\x80\x02\x00\xb2\xcb\xaa\xaa\x04\x80\x02\x00p\r\xaa\xaa\x04\x80\x02\x00]
\xaa\xaa\x04\x80\x02\x00#=\xaa\xaa\x04\x80\x02\x007F\xaa\xaa\x04\x80\x02\x00\!\xaa\xaa\x04\x80\x02\x00=#\xaa\xaa\x04\x80\x02\x00=#\xaa\xaa\x04\x80\x02\x00i\x14\xaa\xaa\x04\x80\x02\x00]
\xaa\xaa\x04\x80\x02\x00p\r\xaa\xaa\x04\x80\x02\x00\x80\xfd\xaa\xaa
I am using python 3.5. This code seems to work in the older versions.
Here is the link to similar parser code where it may have worked with previous versions of Python:
Parser Code Link
Here is the link to the description of how the data is sent from the device
RAW Wave Value (16-bit)
This Data Value consists of two bytes, and represents a single raw wave sample. Its value is a signed 16-bit integer that ranges from -32768 to 32767. The first byte of the Value represents the high-order bits of the twos-compliment value, while the second byte represents the low-order bits. To reconstruct the full raw wave value, simply shift the first byte left by 8 bits, and bitwise-or with the second byte:
short raw = (Value[0]<<8) | Value[2];
where Value[0] is the high-order byte, and Value1 is the low-order byte.
In systems or languages where bit operations are inconvenient, the following arithmetic operations may be substituted instead:
raw = Value[0]*256 + Value[1];
if( raw >= 32768 ) raw = raw - 65536;
Really appreciate any help as I am currently stuck.
When you are using Python 2.x str is a byte array. For Python 3, you must use bytes like this:
struct.unpack("<h", bytes([b, a]))[0]
if you use python3 you can use the following lines for the received data and convert it to a short data type.
struct.unpack('<h', data)
struct.unpack('<h', data[0:4])
struct.unpack('<h', b''.join(…))
If it receives the data as a list, it uses converts the array to bytes:
struct.unpack('<h', bytes(data))
Remember you must convert your information to bytes and not send as str, in order to use unpack and decompress the information in the data type you require.
I have a python method that calculates value and returns it.
The value is
CalcData = 3941269503L.
It is only 32 bit. Yet this is typecasted to long implicitly (suffixed by L) and when I access this method in COM in other application , I get the Python int too large to convert to C long error. I even tried typecasting it into int,but no luck
The "long" C type is signed so the largest positive value it can store is 2,147,483,647. The error is indeed correct, it doesn't fit.
Try "unsigned long" and "UL" postfix on the constant.
How to use built in python function named: struct.unpack in delphi just like what python do.
here is an example:
x = struct.unpack(">H",data[offset:offset+2])[0]
>H is a big endian unsigned two byte value.
In Delphi you would do this:
var
x: Word;
data: TBytes;
....
x := ntohs(PWord(#data[offset])^);
Let's look at this in more detail:
data is an array of bytes and so data[offset] is the value you are trying to unpack.
ntohs converts from network byte order (big endian) to host byte order.
Since the parameter of ntohs is a Word, we need to treat data[offset] as a word and hence the cast.
In order to call ntohs you'll need to use the Winsock unit.
I am trying to read some negative values from a compressed file that has the hex values:
FFFFFFFF, which should be -1, but displays as 4294967295
FFFFFFFE, which should be -2, but displays as 4294967294
I know FF should be the marker for - but is there a method in python that can just read the values directly or do I have to make my own method?
Thank you!
Edit: This is for Python 2.6. My program reads from binary data and I am just displaying it in hex to make it simpler. The program simply reads 4 bytes at a time and grabs values from those 4 bytes. It is just some of those values are negative and display the above numbers. I am also hoping someone can explain how Python interprets the binary data into a value so I can write a reverse protocol. Thank you!
I read from hex and convert to values through this method.
def readtoint(read):
keynumber = read[::-1]
hexoffset=''
for letter in keynumber:
temp=hex(ord(letter))[2:]
if len(temp)==1:
temp="0"+temp
hexoffset += temp
value = int(hexoffset, 16)
return value
It grabs 4 bytes, inverses the order, then converts the hex value into a int value. THe values I posted above are inverted already.
Use the struct module:
import struct
def readtoint(read):
return struct.unpack('<i', read)[0]
Example:
>>> readtoint('\xfe\xff\xff\xff')
-2
Post you file reading code to get the perfect answer. But answer to your question is almost certainly here:
Reading integers from binary file in Python