perl hex() analog in python - python

perl hex() analog in python how to?
I have next perl code:
my $Lon = substr($Hexline,16,8);
say $output_f "Lon: " . hex($Lon) . "";
where $Hexline has "6a48f82d8e828ce82b82..." format
I try it on python
Lon = int(Hexline[16:24], 16)
f.write('lon = %s' % str(Lon)+'\n')
is it right?
EDIT: in perl's case hex() gives me a decimal value.

Yes, to convert an hexadecimal string to an integer you use int(hex_str, 16).
Note that in your write method call:
You don't need to concatenate two strings to add the new line character, you can add it to the formatting string directly.
To print integer you should use %d instead of %s.
You don't really need to call str to transform the integer into a string.
Hence, the write call could be written as:
f.write('lon = %d\n' % Lon)
Alternatively, you could also use format this way:
f.write('lon = {0}\n'.format(Lon))

Related

Convert hex string to usably hex

I want to convert a hex string I read from a file
"0xbffffe43" to a value written in little endian "\x43\xfe\xff\xbf".
I've tried using struct.pack but it requires a valid integer. Everytime I try to cast hex functions it will convert the 43. I need this for an assignment around memory exploits.
I have access to python 2.7
a = "0xbffffe43"
...
out = "\x43\xfe\xff\xbf"
Is what I want to achieve
You have a string in input. You can convert it to an integer using int and a base.
>>> a = "0xbffffe43"
>>> import struct
>>> out = struct.pack("<I",int(a,16))
>>> out
b'C\xfe\xff\xbf'
The b prefix is there because solution was tested with python 3. But it works as python 2 as well.
C is printed like this because python interprets printable characters. But
>>> b'C\xfe\xff\xbf' == b'\x43\xfe\xff\xbf'
True
see:
Convert hex string to int in Python
Convert a Python int into a big-endian string of bytes
You can try doing:
my_hex = 0xbffffe43
my_little_endian = my_hex.to_bytes(4, 'little')
print(my_little_endian)

Trying to understand binary conversion script

I have the following python code, which converts a binary string into plain-text:
import bin ascii
n = int('01100001011000100110001101100100', 2)
binascii.unhexlify('%x' % n)
This code functions properly, but I don't understand what's going on here.
What is the purpose of the "2" at the end of the int declaration?
What is the purpose of the "'%x' % n" argument?
What is the purpose of the 2 at the end of the int declaration?
According to the documentation, int can take a second argument: the base of the first argument.
What is the purpose of the '%x' % n argument?
%x in a string indicates that an item will be formatted to hexadecimal with lowercase letters. '%x' % n. It is similar to the builtin hex function, except it doesn't have the leading 0x in the string. An equivalent expression would be format(n, 'x').

Convert Hexadecimal string to long python

I want to get the value of 99997 in big endian which is (2642804992) and then return the answer as a long value
here is my code in python:
v = 99997
ttm = pack('>i', v) # change the integer to big endian form
print ("%x"), {ttm}
r = long(ttm, 16) # convert to long (ERROR)
return r
Output: %x set(['\x00\x01\x86\x9d'])
Error: invalid literal for long() with base 16: '\x00\x01\x86\x9d'
As the string is already in hex form why isn't it converting to a long? How would I remove this error and what is the solution to this problem.
pack will return a string representation of the data you provide.
The string representation is different than a base 16 of a long number. Notice the \x before each number.
Edit:
try this
ttm = pack('>I',v)
final, = unpack('<I',ttm)
print ttm
Notice the use of I, this so the number is treated as an unsigned value
You have to use struct.unpack as a reverse operation to struct.pack.
r, = unpack('<i', ttm)
this will r set to -1652162304.
You just converted the integer value to big endian binary bytes.
This is useful mostly to embed in messages addressed to big-endian machines (PowerPC, M68K,...)
Converting to long like this means parsing the ttm string which should be 0x1869D as ASCII.
(and the print statement does not work either BTW)
If I just follow your question title: "Convert hexadecimal string to long":
just use long("0x1869D",16). No need to serialize it.
(BTW long only works in python 2. In python 3, you would have to use int since all numbers are represented in the long form)
Well, I'm answering to explain why it's bound to fail, but I'll edit my answer when I really know what you want to do.
This is a nice question.
Here is what you are looking for.
s = str(ttm)
for ch in r"\bx'":
s = s.replace(ch, '')
print(int(s, 16))
The problem is that ttm is similar to a string in some aspects. This is what is looks like: b'\x00\x01\x86\x9d'. Supplying it to int (or long) keeps all the non-hex characters. I removed them and then it worked.
After removing the non-hex-digit chars, you are left with 0001869d which is indeed 99997
Comment I tried it on Python 3. But on Python 2 it will be almost the same, you won't have the b attached to the string, but otherwise it's the same thing.

how to use format specifier on string in python

I want to use format specifier on numbers in string
Alist = ["1,25,56.7890,7.8"]
tokens = Alist[0].split(',')
for number in tokens:
print "%6.2f" %number ,
Outcome: It gives me error.
TypeError: float argument required, not str
Your error clearly states that you are trying to pass a String off as a Float.
You must cast your string value to a float:
for number in tokens:
print '{:6.2f}'.format(float(number))
Note If you are using a version of python earlier than 2.6 you cannot use format()
You will have to use the following:
print '%6.2f' % (float(number),) # This is ugly.
Here is some documentation on Python 2.7 format examples.

from python, how to write an integer into a (hex) bytea field

issue is this: in (pl)python code, we've calculated an integer = 26663.
Can easily convert this to hex using hex(myint) = 0x6827
So far so good!
Now, how to write this value -into a concatenation of strings- into a PostgreSQL (v9) bytea field? The DB is UTF8-encoded, if this matters.
EG, neither of these examples will work:
Here, of course, I cannot concatenate 'str' and 'int' objects:
rv = plpy.execute(plan, [ (string1 + 6827) ])
This one inputs the wrong hex code for 0x6827
rv = plpy.execute(plan, [ (string1 + str('6827')) ])
Help!
I'm not familiar with Postgres, but the hex(n) function returns a string representation of the numeric value of n in hexadecimal. The nicest way in my opinion to concatenate this with a string is to use format strings. For example:
rv = plpy.execute(plan, [ ( 'foo %s bar' % hex(6827) ) ] )
If the string is really in a variable called string1, and you only need to append it with the hex value, then simple concatenation using the + sign will work fine:
rv = plpy.execute(plan, [ ( string1 + hex(6827) ) ])
This works without conversion because the hex() function returns a string.
If you don't actually want to store a printable string representation, but rather a binary string, use the struct module to create an array of bytes.
import struct
bytes = struct.pack('i', 6827) # Ignoring endianness
A lot of people are confused about what storing something as "binary" actually means, and since you are using a field type (bytea) which seems to be intended for binary storage, maybe this is what you actually want?
The returned value from bytes will be a string that you can either concatenate with another string, or continue to pack more binary values into.
See the struct module documentation for more information!

Categories

Resources