Here's how to directly print to a console, although a library like curses is definitely easier.
Figure out what characters your console supports:
import sys
print('encoding =',sys.stdout.encoding)
print(bytes(range(256)).decode(sys.stdout.encoding)
encoding = cp437 โบโปโฅโฆ โซโผโบโโโผยถยงโฌโจโโโโโโโฒโผ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~โรรผรฉรขรคร รฅรงรชรซรจรฏรฎรฌรร รรฆรรดรถรฒรปรนรฟรรยขยฃยฅโงฦรกรญรณรบรฑรยชยบยฟโยฌยฝยผยกยซยปโโโโโคโกโขโโโฃโโโโโโโโดโฌโโโผโโโโโฉโฆโ โโฌโงโจโคโฅโโโโโซโชโโโโโโโฮฑรฮฯฮฃฯยตฯฮฆฮฮฉฮดโฯฮตโฉโกยฑโฅโคโ โกรทโยฐโยทโโฟยฒ โ
Then print them as Unicode characters. Make sure to save the source file in UTF-8 (Python 3's default) or declare the encoding used in the source file with a #coding: encoding comment. UTF-8 can handle any character, but if you print one your terminal doesn't support you'll get a UnicodeEncodeError in pre-3.6 Python.
print('โโโฆโโโโโฅโโโโโคโโโโโฌโโ')
print('โ โ โโ โ โโ โ โโ โ โ')
print('โ โโฌโโฃโโโซโโขโโโชโโกโโโผโโค')
print('โ โ โโ โ โโ โ โโ โ โ')
print('โโโฉโโโโโจโโโโโงโโโโโดโโ')
Answer from Mark Tolonen on Stack Overflowโโโฆโโโโโฅโโโโโคโโโโโฌโโ โ โ โโ โ โโ โ โโ โ โ โ โโฌโโฃโโโซโโขโโโชโโกโโโผโโค โ โ โโ โ โโ โ โโ โ โ โโโฉโโโโโจโโโโโงโโโโโดโโ
Most of the bytes are fine, but instead of
b'5A\x82\x79\x99'
I get
b'Z\x82y\x99'
I don't want 5A converted to a 'Z', nor the 79 to a 'y'.
Im learning crypto ctf with python and there is something that really can't figure out on my own
i have a flag encrypted with XOR with a key. they are represented as hex. after convert it to bytes, i xor them and then use it Crypto.Util.number.long_to_bytes() to find the flag.
before the XOR operation, the bytes values is like "\xa6\xc8\xb6s<\x9b"\xde{\xc0%2f\xa3\x86}\xf5Z\xcd\xe8c^\x19\xc73\x13"
after i removed the key that was XOR with the flag, the bytes values of flag is
crypto{x0r_i5_ass0c1at1v3}
i checked the var with type() and it's a bytes not a str. How come that before that its bytes values has hex values and then only normale characters? Or maybe those arent hex?
Here's how to directly print to a console, although a library like curses is definitely easier.
Figure out what characters your console supports:
import sys
print('encoding =',sys.stdout.encoding)
print(bytes(range(256)).decode(sys.stdout.encoding)
encoding = cp437 โบโปโฅโฆ โซโผโบโโโผยถยงโฌโจโโโโโโโฒโผ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~โรรผรฉรขรคร รฅรงรชรซรจรฏรฎรฌรร รรฆรรดรถรฒรปรนรฟรรยขยฃยฅโงฦรกรญรณรบรฑรยชยบยฟโยฌยฝยผยกยซยปโโโโโคโกโขโโโฃโโโโโโโโดโฌโโโผโโโโโฉโฆโ โโฌโงโจโคโฅโโโโโซโชโโโโโโโฮฑรฮฯฮฃฯยตฯฮฆฮฮฉฮดโฯฮตโฉโกยฑโฅโคโ โกรทโยฐโยทโโฟยฒ โ
Then print them as Unicode characters. Make sure to save the source file in UTF-8 (Python 3's default) or declare the encoding used in the source file with a #coding: encoding comment. UTF-8 can handle any character, but if you print one your terminal doesn't support you'll get a UnicodeEncodeError in pre-3.6 Python.
print('โโโฆโโโโโฅโโโโโคโโโโโฌโโ')
print('โ โ โโ โ โโ โ โโ โ โ')
print('โ โโฌโโฃโโโซโโขโโโชโโกโโโผโโค')
print('โ โ โโ โ โโ โ โโ โ โ')
print('โโโฉโโโโโจโโโโโงโโโโโดโโ')
โโโฆโโโโโฅโโโโโคโโโโโฌโโ โ โ โโ โ โโ โ โโ โ โ โ โโฌโโฃโโโซโโขโโโชโโกโโโผโโค โ โ โโ โ โโ โ โโ โ โ โโโฉโโโโโจโโโโโงโโโโโดโโ
You can use Python curses library, it's a part of standard library on *nix systems, or you can use Urwid that is a higher level library for creating console interfaces.
Constants paragraph of the documentation contains information about how special characters can be drawn in X Emulators (if they support VT100s inherited features). If the emulator doesn't support such alternative character set - ascii approximation is used. I suppose that this is what you're looking for.
After installing my package all-escapes there will be a new codec available for this usage.
>>> b = bytes([10,67,128])
>>> print(b.decode("all-escapes"))
\x0a\x43\x80
There is no specific means of requiring any particular formatting (like \x) for a byte string. If you really need specific formatting, you could use something like the .hex() solution from this question, but wrap it with other code to insert the formatting you need. Another useful tool is the hex builtin function. For instance, if you want \x:
>>> x = bytes([67, 128])
>>> print(''.join(r'\x'+hex(letter)[2:] for letter in x))
\x43\x80
If you just need to be able to visually distinguish the bytes, using hex by itself may work for you (it uses 0x instead of \x):
>>> print(''.join(hex(letter) for letter in x))
0x430x80
There is not a way to make this the default behavior for byte strings. Whatever you do, you're going to have to write code that specifies the display format you want; you can't make Python automatically display printable bytes as \x escapes.
The underlying problem is that in Python3 str is for encoded strings, and likewise print only handles str and thus always enforces some encoding.
To write binary data, directly write bytes to the underlying binary pipe of stdout:
python3 -c 'import sys; sys.stdout.buffer.write(b"\x41\xb3\xde\x41\x42\x43\xad\xde")' | xxd -p
41b3de414243adde
Note that the final 0a is missing because .write adds no newline. Manually add it if it is desired.
In case the data already exists as a string, the latin1 encoding can be used to get equivalent bytes:
python3 -c '
import sys
sys.stdout.buffer.write("\x41\xb3\xde\x41\x42\x43\xad\xde".encode("latin1"))' | xxd -p
41b3de414243adde
I'm not sure if this will help in your case but you can use sys.stdout.buffer:
Note
To write or read binary data from/to the standard streams, use the underlying binary buffer object. For example, to write bytes to stdout, use sys.stdout.buffer.write(b'abc').
$ python3 -c 'import sys; sys.stdout.buffer.write(b"\x41\xb3\xde\x41\x42\x43\xad\xde")' | hexdump -C
00000000 41 b3 de 41 42 43 ad de |A..ABC..|
00000008
Please also note that there is no new line character now that was added by print function.
No, the repr() output is not configurable; it is a debug tool.
You could use binascii.hexlify() to get a hex representation:
>>> test = b'\x83\xf8\x41\x41\x41'
>>> from binascii import hexlify
>>> test = b'\x83\xf8\x41\x41\x41'
>>> print(hexlify(test))
b'83f8414141'
or you could convert each individual 'byte' value to a hex representation:
>>> print("b'{}'".format(''.join('\\x{:02x}'.format(b) for b in test)))
b'\x83\xf8\x41\x41\x41'
This produces an alternative representation.
You can create your own class for this:
class EscapeAll(bytes):
def __str__(self):
return 'b\'{}\''.format(''.join('\\x{:02x}'.format(b) for b in self))
# b'\x31\x32\x33'
print(EscapeAll(b'123'))
That display values is just a representation of the data. Data that is valid ASCII will display the ASCII character, but the bytes are actually:
>>> answ = b'\xaa\x10\xb1?\x86ff\x85'
>>> for i in answ: print(hex(i))
...
0xaa
0x10
0xb1
0x3f
0x86
0x66
0x66
0x85
Is that what you are looking for?
A bytearray is, as the name suggests, an array of bytes. When you receive the data you get the exact bytes that were sent which are then stored in your answ variable. However when you print to the screen python assumes an ASCII encoding so anything that is a printable character is printed as that character and not as the hex, but they are actually the same as the following code snippet shows:
a = b"f"
b = b"\x66"
if a == b:
print("Same")
else:
print("different")
This prints "Same", which you can see in action here: http://ideone.com/6980Ty
Look up an ascii-table to see how the conversions are made. If you are on linux you type man ascii at the terminal to see this.