I'm trying the following:
>>> a = '\01'
>>> a
>>> '\x01'
>>> b = '\11'
>>> b
>>> '\t'
>>> c = '\21'
>>> c
>>> '\x11'
I don't understand why sometimes I get hexadecimal representation and other times not.
In '\xhh' the 'x' is fundamental or not?
Short Answer
You see the hexadecimal representation for those characters for which your native code page cannot represent your characters
Long Answer
Assuming you are using windows, and your default code page is cp1252, '\01' is a non-printable character, an ascii control code, which stands for Start of Heading. As there is no known printable representation of the character, a hexadecimal value is used to display the value.
The numbers \11, \21 are OCTAL numbers. \11 octal is \x09 (hex) is equal to '\t' (tab char). \21 octal is \x11 hex is 17 decimal.
Related
I am learning about strings and bytestrings in python. I don't understand why certain hexadecimal escape sequences are displayed in \XNN form and some are not?
s = 'A\x31\tC'
s1 = 'A\x00B\tC'
In this case, when I type s1 into the console, it prints the exact string of characters within the quotes,'A\x00B\tC', but when I type s into the console, it prints 'A1B\tC'. It is only when I print s1 that the screen shows 'AB C'. I don't understand why certain escape characters are shown and others are not? And why does it then show when you print them?
Cheers
http://www.asciitable.com/
If you look at the ASCII table, you would see that some characters are printable, while others are not.
In particular, \x31 == 1 (Hexadecimal 31 == Decimal 49 == ASCII Character 1.
On the other hand \x00 is not printable. It represents the null terminator (or \0)
>>> '\x31' == '1'
True
>>> '\x00' == '\0'
True
A more interesting question is: Why does \x31 get converted to 1, \x09 gets converted to a \t, while \x00 is not converted to \0. That I don't know.
When you type name into the interpreter, it is using the result of calling repr on that name. Since \x31 can be represented as 1, it uses that. Since \x00 cannot be represented as a printable character, it falls back to using the hex escape notation.
Note that:
>>> '\x31' == '1'
True
So the result of repr is valid.
I have a problem with Python's & bitwise operation:
>>> x = 0xc1
>>> y = 0x7f
>>> x & y
>>> 65
>>> bytes([65])
>>> b'A'
The problem is the conversion from decimal to hex. 65 is 0x41, however Python says that it is 'A'. Why?
The value that you already have is exactly the value you want. From a comment:
I was using bytes function because I want to concat the result of base64.b64decode(coded_string) with one more byte at the end.
bytes([65]) creates a bytes object with a single byte with the numeric value 65. What that number means depends on how you interpret the bytes.
The fact that its repr happens to be b'A' isn't relevant. What the value actually is, is the one byte you want. But the repr of a bytes object, as the docs explain, uses the bytes literal format for convenience. Any byte that matches a printable ASCII character gets represented as that character, a few common values get represented with backslash escapes like \n, and anything else as a hex escape, all within b'…'
So, repr(bytes([65])) is b'A', because byte 65 is the printable ASCII character A.
If you want to get a string with the hexadecimal representation of the number 65, you can use the hex function—or, if you want more control over the formatting, the format function:
>>> hex(65)
'0x41'
>>> format(65, '02x')
'41'
But that's not what you want here. You want the value b'A', and you already have that.
65 is not A in hex, it's A in ASCII code; print(bytes([65])) and print(chr(65)) outputs b'A' and A, respectively (ASCII representations). Hexadecimal is merely a numeral system with 16 as its base. 0x41 is therefore 4 * 16^1 + 1 * 16^0 = 65.
Hi I'm learning pySerial module, so the hex to ascii is its fundamental.
So far I have the following concepts.
Byte String: "\xde"
Byte Array:
>>> bytearray('\xde')
bytearray(b'\xde')
>>> a = bytearray('\xde')
>>> a[0]
222
>>> hex(a[0])
'0xde'
Hex String: '\xde'
Hex: 0xde
Normal representation: de
Now what I need is Hex String to Hex and vice versa.
Also Hex or Hex String to Normal representation .
I wish I can have the simplest possible answer.
Update:
I think I got an initial answer other than string operation.
But this looks really dirty.
>>> hex(int(binascii.hexlify('\xde'),16))
'0xde'
Let me re-write a little.
You have a byte (say b, with an integer value of 222 (in decimal) or de (in hexadecimal) or 276 in octal or 10111110 in binary.
Its hexadecimal string representation is '0xde'
The following initialisations are the same :
b = 222
b = 0xde
Here are the conversions (say s is a string, s='0xde', ie the hexadecimal string representation)
s = hex(b)
b = int(s, 16)
Edit per comment :
If you really want to be able to accept as input \xde as well as 0xde you can do :
b = int('0' + s[1:] if (s[0] == '\\') else s, 16)
or directly
b = int('0' + s[1:], 16)
if you are sure you will never get weird input
I am testing struct module because I would like to send simple commands with parameters in bytes (char) and unsigned int to another application.
However I found some weird things when converting to little endian unsigned int, these examples print the correct hexadecimal representation:
>>> import struct
>>> struct.pack('<I',7)
b'\x07\x00\x00\x00'
>>> struct.pack('<I',11)
b'\x0b\x00\x00\x00'
>>> struct.pack('<I',16)
b'\x10\x00\x00\x00'
>>> struct.pack('<I',15)
b'\x0f\x00\x00\x00'
but these examples apparently not:
>>> struct.pack('<I',10)
b'\n\x00\x00\x00'
>>> struct.pack('<I',32)
b' \x00\x00\x00'
>>> struct.pack('<I',64)
b'#\x00\x00\x00'
I would appreciate any explanation or hint. Thanks beforehand!
Python is being helpful.
The bytes representation will use ASCII characters for any bytes that are printable and escape codes for the rest.
Thus, 0x40 is printed as #, because that's a printable byte. But 0x0a is represented as \n instead, because that is the standard Python escape sequence for a newline character. 0x00 is represented as \x00, a hex escape sequence denoting the NULL byte value. Etc.
All this is just the Python representation when echoing the values, for your debugging benefit. The actual value itself still consists of actual byte values.
>>> b'\x40' == b'#'
True
>>> b'\x0a' == b'\n'
True
It's just that any byte in the printable ASCII range will be shown as that ASCII character rather than a \xhh hex escape or dedicated \c one-character escape sequence.
If you wanted to see only hexadecimal representations, use the binascii.hexlify() function:
>>> import binascii
>>> binascii.hexlify(b'#\x00\x00\x00')
b'40000000'
>>> binascii.hexlify(b'\n\x00\x00\x00')
b'0a000000'
which returns bytes as hex characters (with no prefixes), instead. The return value is of course no longer the same value, you now have a bytestring of twice the original length consisting of characters representing hexadecimal values, literal a through to f and 0 through to 9 characters.
"\xNN" is just the way to represent a non-prinatble character ... it will give you the prinable character if it can
print "\x0a" == "\n" == chr(10)
The general problem is that I need the hexadecimal string stays in that format to assign it to a variable and not to save the coding?
no good:
>>> '\x61\x74'
'at'
>>> a = '\x61\x74'
>>> a
'at'
works well, but is not as:
>>> '\x61\x74'
'\x61\x74' ????????
>>> a = '\x61\x74'
>>> a
'\x61\x74' ????????
Use r prefix (explained on SO)
a = r'\x61\x74'
b = '\x61\x74'
print (a) #prints \x61\x74
print (b) # prints at
It is the same data. Python lets you specify a literal string using different methods, one of which is to use escape codes to represent bytes.
As such, '\x61' is the same character value as 'a'. Python just chooses to show printable ASCII characters as printable ASCII characters instead of the escape code, just because that makes working with bytestrings that much easier.
If you need the literal slash, x character and the two digit 6 and 1 characters (so a string of length 4), you need to double the slash or use raw strings.
To illustrate:
>>> '\x61' == 'a' # two notations for the same value
True
>>> len('\x61') # it's just 1 character
1
>>> '\\x61' # escape the escape
'\\x61'
>>> r'\x61' # or use a raw literal instead
'\\x61'
>>> len('\\x61') # which produces 4 characters
4