C to Python code conversion(print address-like values) - python

I am trying to convert the following code from c to Python. The C code looks like:
seed = (time(0) ^ (getpid() << 16));
fprintf("0x%08x \n", seed);
that outputs values like 0x7d24defb.
And the python code:
time1 = int(time.time())
seed = (time1 ^ (os.getpid() <<16))
that outputs values like: 1492460964
What do i need to modify at the python code so I get address-like values?

It depends on the way the value is displayed. The %x flag in printf-functions displays the given value in hexadecimal. In Python you can use the hex function to convert the value to a hexadecimal representation.

The equivalent Python code to: fprintf("0x%08x \n", seed);
>>> '0x{:08x}"'.format(1492460964)
'0x58f525a4"'
Note that hex() alone won't pad zeros to size 8 like the C code does.

I suppose this is what you what:
>>> n =hex (int(time.time()) ^ (os.getpid() <<16))
>>> print n
0x431c2fd2
>>>

Related

Why does to_bytes(2, byteorder="big") return sometimes only one byte?

I really don't understand why does sometimes to_bytes return not what I want.
For instance, here is an expected behavior :
i = 12
i.to_bytes(2, byteorder="big")
>> b'\x00\x0c'
However, here is sometimes the output :
i = 870
i.to_bytes(2, byteorder="big")
>> b'\x03f'
while I would like to have :
>> b'\x03\x66'
Does anyone have any clue ? Is there another way to obtain what I want ?
Thanks a lot !
I tried other method with format, hex, ... but I really want bytes in hexadecimal format with '\x' ...
The method to_bytes() (in your case) produces a byte array of length 2. It renders however python wants to render it.
If you want it printed differently, you can convert it to a string like this:
i = 12
byts = i.to_bytes(2, byteorder="big")
out = ''.join(f'\\x{b:02x}' for b in byts)
print(out)
Output:
\x03\x66
Note that the output is a string and not a byte array.

How to understand bytes output in python?

I am using struct for creating byte like objects out of arrays. Here is my code:
import numpy as np
import struct
a = 1
a = np.array(a,dtype=np.int32)
format_charecters = f'<1I'
bytes_ = struct.pack(format_charecters,*a.flatten())
bytes_
The code outputs:
b'\x01\x00\x00\x00'
This makes sense to me as I am using < little-endian byte-ordering and referring the following table 1 should correspond to \x01 where x represents hexadecimal.
Now when I replace 1 with 10 I get a surprising result:
b'\n\x00\x00\x00'
I was not expecting this... I thought the output will be:
b'\x0a\x00\x00\x00'
Also for some random value a = 1324233699 I get:
b'\xe33\xeeN'
Using an online decimal-hex converter I get:
4EEE33E3
How to interpret the results of my code?
The link deadshot gave perfectly explained my question. I am adding a screenshot of the table of escape characters in python so that other people can find it even if the 'tutorialspoint' site goes down.

unpacking pythons struct.pack in another language

I want to "unpack" OR de-serialize the formatted data that is outputed from python's struct.pack() function. The data is sent over the network to another platform that uses Java only.
The Python function that sends data over the network, uses this formater:
def formatOutputMsg_Array(self, mac, arr):
mac_bin = mac.encode("ascii");
mac_len = len(mac_bin);
arr_bin = array.array('d', arr).tobytes();
arr_len = len(arr_bin);
m = struct.pack('qqd%ss%ss' % (mac_len, arr_len), mac_len, arr_len, time.time(), mac_bin, arr_bin);
return m
Here are the docs for python's struct (refer to section 7.3.2.2. Format Characters):
https://docs.python.org/2/library/struct.html
1) The issue is what does 'qqd%ss%ss' mean ???
Does it mean -> long,long,double,char,char,[],char[],char,char[],char[]
2) why is modulo "%" used here with a tuple 'qqd%ss%ss' % (mac_len, arr_len) ?
The first argument to pack is the result of the expression 'qqd%ss%ss' % (mac_len, arr_len), where the two %s are replaced by the values of the given variables. Assuming mac_len == 8 and arr_len == 4, for example, the result is qqd8s4s. s preceded by a number simply means to copy the given bytes for that format into the result.

Hex To Int In Python No Int Constructor

I'm trying to turn a string representing a Hexidecimal number into an int in python without using the int constructor.
For example if I was given
hexstring = "802"
How would I get that to be
output = 2050
Without doing
int("802",16)
How would I go about this?
hexstring = "802"
L=len(hexstring)
def val(h_char):
# Note you need to extend this to make sure the lowercase hex digits are processed properly
return ord(h_char)- (55 if ord(h_char)>64 else 48)
def sumup(sum,idx):
global hexstring # global variables are not recommended
L=len(hexstring)
return sum + 16**idx*val(hexstring[L-idx-1])
output = reduce(lambda a,b:sumup(a,b),range(L),0))
Below is just an explanation of the above and doesn't add any value
Processes on a list of [0,1,2] produced by range(L).
For each idx from above list a function call is made as sumup(sum, idx)=sum+16^idx*h_digit_at_idx.(^ is ** is exp in above)
h_digit_at_idx = ord(h_char)- (55 if ord(h_char)>64 else 48)
ord(h_char) produces 48,49...57,65,66,67,68,69,70 for hex characters 0,1...10,A,B,C,D,E,F
ord(h_char)-(55 if ord(h_char)>64 else 48 produces 0,1...10,11,12,13,14,15 for respective chars.
Finally the last argument of the reduce function is 0(which is the initial sum to start with)

Python bitstring uint seen as long

I have the following:
I read 30 bits from a bitstream:
MMSI = b.readlist('uint:30')
This seems to work normally except when the values get higher.
MMSI = b.readlist('uint:30')
p = 972128254
# repr(MMSI)[:-1]
print p
print "MMSI :"
print MMSI
if MMSI == p:
The code above outputs:
972128254
MMSI :
[972128254L]
The whole if MMSI ==p: is skipped for it is not equal for some reason.
I do not understand why the value that is far lower than max.int:
>>> import sys
>>> sys.maxint
2147483647
I do not understand why I get a Long returned and not a uint?
If the value returned is 244123456 it works like a charm.
2147483647 is maxint, but an int is 32 bits and you're using 30 bits. So your max is 1/4 of that, or about 500 million.
Values will be 'long' if an intermediate value was a long. So for example 2**1000 / 2**999 will equal 2L. This is just to do with the internals of the method you called and shouldn't affect most code.
The real problem is the comparison you have in your code is comparing an int to a list, which is not what you want to do. You can either use the read method rather than readlist to return a single item, or take the first element of the returned list: if MMSI[0] == p:
Aha, I figured that if I read 30bits and returned it as uint value it would automatically be a 32bits value.
So what you are saying is that I would have to add leading zeros to make a 32 bit value and then it should work.
So that is what I have tested and now I am lost.
I figured lets encode the value I want to compare to in the same way. So this is what I did:
from bitarray import bitarray
from bitstring import BitArray, BitStream,pack
from time import sleep
import string
MMSI = b.readlist('uint:30')
x = pack('uint:30',972000000)
p = x.readlist('uint:30')
y = pack('uint:30',972999999)
q = y.read('uint:30')
print p
print q
print x
print y
print MMSI
resulting in:
p = [972000000L]
q = 972999999
x = 0b111001111011111000101100000000
y = 0b111001111111101100110100111111
MMSI = [972128254L]
How can it be that the higher value 972999999 is not a long?

Categories

Resources