I am using Python 3.5.2
I know that with print("\x00") (where 0 is an ASCII character) I can print symbols with hex format. But how can I print number 500,000 (in hex: 7A120) when print("\x00") takes only 2 characters?
To print a constant hexidecimal expression, you can prefix the number with a 0x, and it will resolve to an int with the equivalent base 10 value, like so:
>>> print(0x7A120)
500000
If you want to print a string with arbitrary hexidecimal characters in it, use int:
>>> a = "7A120"
>>> print(int(a, 16))
500000
The second argument to int is the base to parse the string from, in this case base 16 (hex).
To print an integer in hexidecimal format, use the format operator, %:
>>> a = 0x7A120
>>> print("%x" % a)
7a120
You can change the "x" in "%x" to uppercase to print a through f in uppercase:
>>> b = 0xABCDEF
>>> print("%x" % b)
abcdef
>>> print("%X" % b)
ABCDEF
Related
I want to create a new binary file by using python according to the following format:
< Part1: 8 bytes > < Part2: 4 bytes > < Part3: 16 bytes>
so that i will write to any part some value and if this value is not the size of that part, then there will be a complement of zeros for that part.
I looking for the best way and the most efficient way to do it.
I read in the internet that I can do something like that:
f = open('file', 'w+b')
res = struct.pack(">l", 0000)
f.write(res)
but I don't sure that i can by this way to keep a place from the hand.
Let's start with some terminology when working with Python data before getting to your code to write a binary file.
Note: The experiments below are using the Python REPL
An integer in Python can be written as a denary/decimal number (e.g. 1)
>>> type(1)
<class 'int'>
It can also be written in hex by adding a leading 0x:
>>> 0x1
1
>>> type(0x1)
<class 'int'>
A hex integer's leading zeros have no effect. While in denary they give an error:
>>> x = 0x0001
>>> print(x)
1
>>> x = 0001
x = 0001
^^^
SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers
When writing to a binary file it is bytes that need to get written. If the content is an integer it can be converted to bytes with either the int.to_bytes functionality or the struct library functionality.
To convert 1 to bytes using int.to_bytes:
>>> int(1).to_bytes(length=1, byteorder='little')
b'\x01'
With a length of 1 the byte order (endianness) is not important. For numbers stored in more bytes it is important.
>>> int(1).to_bytes(length=4, byteorder='little')
b'\x01\x00\x00\x00'
>>> int(1).to_bytes(length=4, byteorder='big')
b'\x00\x00\x00\x01'
The same result can be achieved with the struct library:
>>> struct.pack('<l', 1)
b'\x01\x00\x00\x00'
>>> struct.pack('>l', 1)
b'\x00\x00\x00\x01'
The other common way to see values written is a hex string. The denary value of 1 could be written as 01000000 or 00000001 to represent 1 in different endian in 4 bytes.
>>> int(1).to_bytes(length=4, byteorder='big').hex()
'00000001'
>>> int(1).to_bytes(length=4, byteorder='little').hex()
'01000000'
In your question you have written 0000 for the value to be converted using struct and written to a file.
f = open('file', 'w+b')
res = struct.pack(">l", 0000)
f.write(res)
0000 will work but 0001 will give the SyntaxError: leading zeros in decimal integer literals are not permitted;
I think what you have in your question is the hex string representation of the value you want written.
If it is a hex string you are trying to input then the following will work:
f = open('file', 'w+b')
res = bytes.fromhex('0001')
f.write(res)
The other piece in your question was about making the values to certain byte length.
If your hex string represents the correct byte length then you are good.
However the example you gave was only 2 bytes long:
bytes.fromhex('0001')
b'\x00\x01'
len(bytes.fromhex('0001'))
2
And you wanted fields of either 4, 8, or 16 bytes long in which case the bytes have to be "padded` with bytes of zero value to get the correct number of bytes. e.g.
>>> bytes.fromhex('0001').rjust(4, b'\x00')
b'\x00\x00\x00\x01'
>>> bytes.fromhex('0001').rjust(8, b'\x00')
b'\x00\x00\x00\x00\x00\x00\x00\x01'
>>> bytes.fromhex('0001').rjust(16, b'\x00')
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
If the hex string are in little endian format then ljust would be required:
bytes.fromhex('0100').ljust(4, b'\x00')
b'\x01\x00\x00\x00'
I'm having an issue getting from hexadecimal string to hexadecimal integer in Python 3.
When you write hex(12) you get the output 0xc which is a str class. However, when you type fx. int = 0x55 the class/type is an INTEGER.
How do you go from "0x55" to 0x55 (as an integer)
Thank you :)
You might be getting confused between the concepts of a number's representation and a number's value. For example, the following evaluates to True in Python: 83 == 0o123 == 0x53 The decimal representation is 83, and octal representation is 123, and the hexadecimal representation is 53. However, the value of all those representations are the same. For the sake of explanation, I will give you the value using the decimal representations; the value is 83.
If you are trying to convert a string into a number, you may want to look at the eval and ast.literal_eval functions. Here is a demonstration of how you might use the second:
>>> number = 12345
>>> hex_string = hex(number)
>>> oct_string = oct(number)
>>> print('hex_string =', repr(hex_string))
hex_string = '0x3039'
>>> print('oct_string =', repr(oct_string))
oct_string = '0o30071'
>>> number == ast.literal_eval(hex_string)
True
>>> number == ast.literal_eval(oct_string)
True
>>>
How do I format the following numbers that are in vector?
For an instance, numbers which I have:
23.02567
0.025679
and I would like to format to this:
0.230256700+E02
0.025679000+E00
First, note that this is not the proper way to format numbers in scientific- or engineering-notation. Those numbers should always have exactly one digit in front of the decimal point, unless the exponent is required to be a multiple of 3 (i.e. a power of 1000, corresponding to one of the SI prefixes). If, however, you have to use this format, you could write your own format string for that.
>>> x, e = 23.02567, 2
>>> "%f%sE%02d" % (x/10**e, "+" if e >= 0 else "-", abs(e))
'0.230257+E02'
>>> x, e = 0.025679, -1
>>> "%f%sE%02d" % (x/10**e, "+" if e >= 0 else "-", abs(e))
'0.256790-E01'
This is assuming that the exponent, e, is given. If the exponent does not matter, you could also use the proper %E format and just replace E+ with +E:
>>> ("%E" % x).replace("E+", "+E").replace("E-", "-E")
'2.567900-E02'
I'm Trying to delete 2 chars from start of the str and 1 char from the end
import urllib3
target_url="www.klimi.hys.cz/nalada.txt"
http = urllib3.PoolManager()
r = http.request('GET', target_url)
print(r.status)
print(r.data)
print()
And Output is
200
b'smutne'
I need to output be only "smutne", only this, not the " b' " and " ' "
When you have bytes, you'll need them to decode it into a string with the appropriate encoding type. For example, if you have a ASCII characters as bytes, you can do:
>>> foo = b'mystring'
>>> print(foo)
b'mystring'
>>> print(foo.decode('ascii'))
'mystring'
Or, more commonly, you probably have Unicode characters (which includes most of the ASCII character codes too):
>>> print(foo.decode('utf-8'))
'mystring'
This will work if you have glyphs with accents and such.
More on Python encoding/decoding here: https://docs.python.org/3/howto/unicode.html
In the particular case of urllib3, r.data returns bytes that you'll need to decode in order to use as a string if that's what you want.
I want to take a string such as:
'\\xeb\\x4d'
and turn it into:
b'\xeb\x4d'
If I do:
bytes('\\xeb\\x4d', 'utf-8')
I get:
b'\\xeb\\x4d'
I need something that does the following:
something('\\xeb\\x4d') == b'\xeb\x4d'
>>> a = '\\xeb\\x4d' # a Unicode string
>>> a.encode('latin1') # get a byte string
b'\\xeb\\x4d'
>>> a.encode('latin1').decode('unicode_escape') # unescape, get a Unicode string
'ëM'
>>> a.encode('latin1').decode('unicode_escape').encode('latin1') # get a byte string
b'\xebM'
>>> a.encode('latin1').decode('unicode_escape').encode('latin1') == b'\xeb\x4d'
True
Note that latin1 is the first 256 codepoints of Unicode, so encoding the first 256 bytes of Unicode gives the same byte values as the original codepoint.
a = '\\xeb\\x4d'
a = bytes(a, 'utf-8')
a = a.decode('unicode_escape').encode('latin1')
gives
b'\xebM'
because
'\x4d' == 'M'