How can I format an integer to a two digit hex? - python

Does anyone know how to get a chr to hex conversion where the output is always two digits?
for example, if my conversion yields 0x1, I need to convert that to 0x01, since I am concatenating a long hex string.
The code that I am using is:
hexStr += hex(ord(byteStr[i]))[2:]

You can use string formatting for this purpose:
>>> "0x{:02x}".format(13)
'0x0d'
>>> "0x{:02x}".format(131)
'0x83'
Edit: Your code suggests that you are trying to convert a string to a hexstring representation. There is a much easier way to do this (Python2.x):
>>> "abcd".encode("hex")
'61626364'
An alternative (that also works in Python 3.x) is the function binascii.hexlify().

You can use the format function:
>>> format(10, '02x')
'0a'
You won't need to remove the 0x part with that (like you did with the [2:])

If you're using python 3.6 or higher you can also use fstrings:
v = 10
s = f"0x{v:02x}"
print(s)
output:
0x0a
The syntax for the braces part is identical to string.format(), except you use the variable's name. See https://www.python.org/dev/peps/pep-0498/ for more.

htmlColor = "#%02X%02X%02X" % (red, green, blue)

The standard module binascii may also be the answer, namely when you need to convert a longer string:
>>> import binascii
>>> binascii.hexlify('abc\n')
'6162630a'

Use format instead of using the hex function:
>>> mychar = ord('a')
>>> hexstring = '%.2X' % mychar
You can also change the number "2" to the number of digits you want, and the "X" to "x" to choose between upper and lowercase representation of the hex alphanumeric digits.
By many, this is considered the old %-style formatting in Python, but I like it because the format string syntax is the same used by other languages, like C and Java.

The simpliest way (I think) is:
your_str = '0x%02X' % 10
print(your_str)
will print:
0x0A
The number after the % will be converted to hex inside the string, I think it's clear this way and from people that came from a C background (like me) feels more like home

Related

How to print byte representation of a string?

So I have a string like "abcd" and I want to convert it into bytes and print it.
I tried print(b'abcd') which prints exactly b'abcd' but I want '\x61\x62\x63\x64'.
Is there a single function for this purpose or do I have to use unhexlify with join?
Note: This is a simplified example of what I'm acutally doing. I need the aforementioned representation for a regex search.
There's no single function to do it, so you would need to do the formatting manually:
s = 'abcd'
print(r'\x' + r'\x'.join(f'{b:02x}' for b in bytes(s, 'utf8')))
Output:
\x61\x62\x63\x64
You can get hex values of a string like this:
string = "abcd"
print(".".join(hex(ord(c))[2:] for c in string))

Convert a symbol to its 4 digit unicode escape representation and vice versa

1) How can I convert a symbol to its 4 digit Unicode escape representation in python 2.7
e.g "¥" to "\u00a5"?
2) How can I convert a Unicode representation to the symbol notation on Windows 7/8 platform
e.g "\u00a5" to "¥"?
1) Does it need to be \u-escaped? Will \x work? If so, try the unicode_escape codec. Otherwise, you can convert using the function below:
def four_digit_escape(string):
return u''.join(char if 32 <= ord(char) <= 126 else u'\\u%04x'%ord(char) for char in string)
symbol = u"hello ¥"
print symbol.encode('unicode_escape')
print four_digit_escape(symbol)
2) Similarly, you can use the unicode_escape codec:
encoded_symbol = '\\u00a5'
print encoded_symbol
print encoded_symbol.decode('unicode_escape')
The most reliable way I found to do this in python is to first decode it into unicode, get the ord of the unicode character and plug that into a format string. It looks like this:
"\\u%04x" % ord("¥".decode("utf-8"))
There is also a method unichr that is supposed to output something like this, but on my system it displays a different encoding than what the op wanted. So the above solution is the most platform independent way that I can think of.

How to use hex() without 0x in Python?

The hex() function in python, puts the leading characters 0x in front of the number. Is there anyway to tell it NOT to put them? So 0xfa230 will be fa230.
The code is
import fileinput
f = open('hexa', 'w')
for line in fileinput.input(['pattern0.txt']):
f.write(hex(int(line)))
f.write('\n')
(Recommended)
Python 3 f-strings: Answered by #GringoSuave
>>> i = 3735928559
>>> f'{i:x}'
'deadbeef'
Alternatives:
format builtin function (good for single values only)
>>> format(3735928559, 'x')
'deadbeef'
And sometimes we still may need to use str.format formatting in certain situations #Eumiro
(Though I would still recommend f-strings in most situations)
>>> '{:x}'.format(3735928559)
'deadbeef'
(Legacy) f-strings should solve all of your needs, but printf-style formatting is what we used to do #msvalkon
>>> '%x' % 3735928559
'deadbeef'
Without string formatting #jsbueno
>>> i = 3735928559
>>> i.to_bytes(4, "big").hex()
'deadbeef'
Hacky Answers (avoid)
hex(i)[2:] #GuillaumeLemaître
>>> i = 3735928559
>>> hex(i)[2:]
'deadbeef'
This relies on string slicing instead of using a function / method made specifically for formatting as hex. This is why it may give unexpected output for negative numbers:
>>> i = -3735928559
>>> hex(i)[2:]
'xdeadbeef'
>>> f'{i:x}'
'-deadbeef'
Use this code:
'{:x}'.format(int(line))
it allows you to specify a number of digits too:
'{:06x}'.format(123)
# '00007b'
For Python 2.6 use
'{0:x}'.format(int(line))
or
'{0:06x}'.format(int(line))
You can simply write
hex(x)[2:]
to get the first two characters removed.
Python 3.6+:
>>> i = 240
>>> f'{i:x}' # 02x to pad with zeros
'f0'
Old style string formatting:
In [3]: "%x" % 127
Out[3]: '7f'
New style
In [7]: '{:x}'.format(127)
Out[7]: '7f'
Using capital letters as format characters yields uppercase hexadecimal
In [8]: '{:X}'.format(127)
Out[8]: '7F'
Docs are here.
'x' - Outputs the number in base 16, using lower-case letters for the digits above 9.
>>> format(3735928559, 'x')
'deadbeef'
'X' - Outputs the number in base 16, using upper-case letters for the digits above 9.
>>> format(3735928559, 'X')
'DEADBEEF'
You can find more information about that in Python's documentation:
Format Specification Mini-Language
format()
F-strings
Python 3's formatted literal strings (f-strings) support the Format Specification Mini-Language, which designates x for hexadecimal numbers. The output doesn't include 0x.
So you can do this:
>>> f"{3735928559:x}"
'deadbeef'
See the spec for other bases like binary, octal, etc.
Edit: str.removeprefix
Since Python 3.9, there is now a str.removeprefix method, which allows you to write the following more obvious code:
>>> hexadecimal = hex(3735928559)
>>> hexadecimal.removeprefix('0x')
'deadbeef'
Not that this does NOT work for negative numbers ❌:
>>> negadecimal = hex(-3735928559)
>>> negadecimal.removeprefix('0x')
'-0xdeadbeef'
Besides going through string formatting, it is interesting to have in mind that when working with numbers and their hexadecimal representation we usually are dealing with byte-content, and interested in how bytes relate.
The bytes class in Python 3 had been enriched with methods over the 3.x series, and int.to_bytes combined with the bytes.hex() provide full control of the hex-digits output, while preserving the semantics of the transform (not to mention, holding the intermediate "bytes" object ready to be used in any binary protocol that requires the number):
In [8]: i = 3735928559
In [9]: i.to_bytes(4, "big").hex()
Out[9]: 'deadbeef'
Besides that, bytes.hex() allow some control over the output, such as specifying a separator for the hex digits:
In [10]: bytes.hex?
Docstring:
Create a string of hexadecimal numbers from a bytes object.
sep
An optional single character or byte to separate hex bytes.
bytes_per_sep
How many bytes between separators. Positive values count from the
right, negative values count from the left.
Example:
>>> value = b'\xb9\x01\xef'
>>> value.hex()
'b901ef'
>>> value.hex(':')
'b9:01:ef'
>>> value.hex(':', 2)
'b9:01ef'
>>> value.hex(':', -2)
'b901:ef'
(That said, in most scenarios just a quick print is wanted, I'd probably just go through f-string formatting, as in the accepted answer: f"{mynumber:04x}" - for the simple reason of "less things to remember")
While all of the previous answers will work, a lot of them have caveats like not being able to handle both positive and negative numbers or only work in Python 2 or 3. The version below works in both Python 2 and 3 and for positive and negative numbers:
Since Python returns a string hexadecimal value from hex() we can use string.replace to remove the 0x characters regardless of their position in the string (which is important since this differs for positive and negative numbers).
hexValue = hexValue.replace('0x','')
EDIT: wjandrea made a good point in that the above implementation doesn't handle values that contain 0X instead of 0x, which can occur in int literals. With this use case in mind, you can use the following case-insensitive implementation for Python 2 and 3:
import re
hexValue = re.sub('0x', '', hexValue, flags=re.IGNORECASE)
Decimal to Hexadecimal,
it worked
hex(number).lstrip("0x").rstrip("L")

Print confusion

I am new to python when i try to print "\20%" that is
>>>"\20%"
why is the shell printing '\x10%' that is, it is showing
'\x10%'
the same is happening with join also when is do
>>>l = ['test','case']
>>>"\20%".join(l)
it shows
'test\x10%case'
I am using python 2.7.3
'\20' is an octal literal, and the same as chr(2 * 8 + 0) == chr(16).
What the Python shell displays by default is not the output of print, but the representation of the given value, which is the hexadecimal '\x10'.
If you want the string \20%, you have to either escape the backaslash ('\\20%') or use a raw string literal (r'\20%'). Both will be displayed as
>>> r'\20%'
'\\20%'
\20 is an escape sequence that refers to the DLE ASCII character whose decimal value is 16 (20 in octal, 10 in hexadecimal). Such a character is printed as the \x10 hex escape by the repr function of strings.
To specify a literal \20, either double the backslash ("\\20") or use a raw string (r"\20").
Two print "\20%"
what if you print directly:
>>> print '\20%'
% # some symbol not correctly display on this page
and do using r
>>> print r'\20%'
\20%
>>> r'\20%' # what r do.
'\\20%'
>>> print '\\20%'
\20%
>>>
Some time back I had same doubt about string and I asked a question, you may find helpful

How to convert an int to a hex string?

I want to take an integer (that will be <= 255), to a hex string representation
e.g.: I want to pass in 65 and get out '\x41', or 255 and get '\xff'.
I've tried doing this with the struct.pack('c',65), but that chokes on anything above 9 since it wants to take in a single character string.
You are looking for the chr function.
You seem to be mixing decimal representations of integers and hex representations of integers, so it's not entirely clear what you need. Based on the description you gave, I think one of these snippets shows what you want.
>>> chr(0x65) == '\x65'
True
>>> hex(65)
'0x41'
>>> chr(65) == '\x41'
True
Note that this is quite different from a string containing an integer as hex. If that is what you want, use the hex builtin.
This will convert an integer to a 2 digit hex string with the 0x prefix:
strHex = "0x%0.2X" % integerVariable
What about hex()?
hex(255) # 0xff
If you really want to have \ in front you can do:
print '\\' + hex(255)[1:]
Let me add this one, because sometimes you just want the single digit representation
( x can be lower, 'x', or uppercase, 'X', the choice determines if the output letters are upper or lower.):
'{:x}'.format(15)
> f
And now with the new f'' format strings you can do:
f'{15:x}'
> f
To add 0 padding you can use 0>n:
f'{2034:0>4X}'
> 07F2
NOTE: the initial 'f' in f'{15:x}' is to signify a format string
Try:
"0x%x" % 255 # => 0xff
or
"0x%X" % 255 # => 0xFF
Python Documentation says: "keep this under Your pillow: http://docs.python.org/library/index.html"
For Python >= 3.6, use f-string formatting:
>>> x = 114514
>>> f'{x:0x}'
'1bf52'
>>> f'{x:#x}'
'0x1bf52'
If you want to pack a struct with a value <255 (one byte unsigned, uint8_t) and end up with a string of one character, you're probably looking for the format B instead of c. C converts a character to a string (not too useful by itself) while B converts an integer.
struct.pack('B', 65)
(And yes, 65 is \x41, not \x65.)
The struct class will also conveniently handle endianness for communication or other uses.
With format(), as per format-examples, we can do:
>>> # format also supports binary numbers
>>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)
'int: 42; hex: 2a; oct: 52; bin: 101010'
>>> # with 0x, 0o, or 0b as prefix:
>>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)
'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010'
Note that for large values, hex() still works (some other answers don't):
x = hex(349593196107334030177678842158399357)
print(x)
Python 2: 0x4354467b746f6f5f736d616c6c3f7dL
Python 3: 0x4354467b746f6f5f736d616c6c3f7d
For a decrypted RSA message, one could do the following:
import binascii
hexadecimals = hex(349593196107334030177678842158399357)
print(binascii.unhexlify(hexadecimals[2:-1])) # python 2
print(binascii.unhexlify(hexadecimals[2:])) # python 3
(int_variable).to_bytes(bytes_length, byteorder='big'|'little').hex()
For example:
>>> (434).to_bytes(4, byteorder='big').hex()
'000001b2'
>>> (434).to_bytes(4, byteorder='little').hex()
'b2010000'
This worked best for me
"0x%02X" % 5 # => 0x05
"0x%02X" % 17 # => 0x11
Change the (2) if you want a number with a bigger width (2 is for 2 hex printned chars) so 3 will give you the following
"0x%03X" % 5 # => 0x005
"0x%03X" % 17 # => 0x011
Also you can convert any number in any base to hex. Use this one line code here it's easy and simple to use:
hex(int(n,x)).replace("0x","")
You have a string n that is your number and x the base of that number. First, change it to integer and then to hex but hex has 0x at the first of it so with replace we remove it.
I wanted a random integer converted into a six-digit hex string with a # at the beginning. To get this I used
"#%6x" % random.randint(0xFFFFFF)
As an alternative representation you could use
[in] '%s' % hex(15)
[out]'0xf'

Categories