Is is possible to concatenate bytes to str?
>>> b = b'this is bytes'
>>> s = 'this is string'
>>> b + s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes
>>>
It is not possible based on simple code above.
The reason I'm asking this as I've seen a code where bytes has been concatenated to str?
Here is the snipet of the code.
buf = ""
buf += "\xdb\xd1\xd9\x74\x24\xf4\x5a\x2b\xc9\xbd\x0e\x55\xbd"
buffer = "TRUN /.:/" + "A" * 2003 + "\xcd\x73\xa3\x77" + "\x90" * 16 + buf + "C" * (5060 - 2003 - 4 - 16 - len(buf))
You can see the full code here.
http://sh3llc0d3r.com/vulnserver-trun-command-buffer-overflow-exploit/
Either encode the string to bytes to get a result in bytes:
print(b'byte' + 'string'.encode())
# b'bytestring'
Or decode the bytes into a string to get a result as str:
print(b'byte'.decode() + 'string')
# bytestring
The second code snippet shows strings being concatenated. You will need to convert the bytes to a string (as shown in the question Convert bytes to a string). Try this: b.decode("utf-8") + s. It should give you the output you need.
Related
I want to pack my data to send it with socket.
I did it.
sensor = b'cam'
msg = struct.pack('3s >I >I', sensor, len(channel), len(inf_bytes)) + channel + inf_bytes ```
And the I got: struct.error: bad char in struct format
Could you tell me where I am wrong?
Only the first character in the format string can be > to use big-endian:
>>> struct.pack('3s>I>I', b'A', 2, 3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: bad char in struct format
>>> struct.pack('>3sII', b'A', 2, 3)
b'A\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03'
The doc says it: (emphasis mine)
By default, C types are represented in the machine’s native format and byte order, and properly aligned by skipping pad bytes if necessary (according to the rules used by the C compiler).
Alternatively, the first character of the format string can be used to indicate the byte order, size and alignment of the packed data, according to the following table:
at https://docs.python.org/3/library/struct.html#struct-format-strings
It's possible to print the hexcode of the emoji with u'\uXXX' pattern in Python, e.g.
>>> print(u'\u231B')
⌛
However, if I have a list of hex code like 231B, just "adding" the string won't work:
>>> print(u'\u' + ' 231B')
File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: truncated \uXXXX escape
The chr() fails too:
>>> chr('231B')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required (got type str)
My first part of the question is given the hexcode, e.g. 231A how do I get the str type of the emoji?
My goal is to getting the list of emojis from https://unicode.org/Public/emoji/13.0/emoji-sequences.txt and read the hexcode on the first column.
There are cases where it ranges from 231A..231B, the second part of my question is given a hexcode range, how do I iterate through the range to get the emoji str, e.g. 2648..2653, it is possible to do range(2648, 2653+1) but if there's a character in the hexa, e.g. 1F232..1F236, using range() is not possible.
Thanks #amadan for the solutions!!
TL;DR
To get a list of emojis from https://unicode.org/Public/emoji/13.0/emoji-sequences.txt into a file.
import requests
response = requests.get('https://unicode.org/Public/emoji/13.0/emoji-sequences.txt')
with open('emoji.txt', 'w') as fout:
for line in response.content.decode('utf8').split('\n'):
if line.strip() and not line.startswith('#'):
hexa = line.split(';')[0]
hexa = hexa.split('..')
if len(hexa) == 1:
ch = ''.join([chr(int(h, 16)) for h in hexa[0].strip().split(' ')])
print(ch, end='\n', file=fout)
else:
start, end = hexa
for ch in range(int(start, 16), int(end, 16)+1):
#ch = ''.join([chr(int(h, 16)) for h in ch.split(' ')])
print(chr(ch), end='\n', file=fout)
Convert hex string to number, then use chr:
chr(int('231B', 16))
# => '⌛'
or directly use a hex literal:
chr(0x231B)
To use a range, again, you need an int, either converted from a string or using a hex literal:
''.join(chr(c) for c in range(0x2648, 0x2654))
# => '♈♉♊♋♌♍♎♏♐♑♒♓'
or
''.join(chr(c) for c in range(int('2648', 16), int('2654', 16)))
(NOTE: you'd get something very different from range(2648, 2654)!)
Here is the I am trying:
import struct
#binary_data = open("your_binary_file.bin","rb").read()
#your binary data would show up as a big string like this one when you .read()
binary_data = '\x44\x69\x62\x65\x6e\x7a\x6f\x79\x6c\x70\x65\x72\x6f\x78\x69\x64\x20\x31\
x32\x30\x20\x43\x20\x30\x33\x2e\x30\x35\x2e\x31\x39\x39\x34\x20\x31\x34\x3a\x32\
x34\x3a\x33\x30'
def search(text):
#convert the text to binary first
s = ""
for c in text:
s+=struct.pack("b", ord(c))
results = binary_data.find(s)
if results == -1:
print ("no results found")
else:
print ("the string [%s] is found at position %s in the binary data"%(text, results))
search("Dibenzoylperoxid")
search("03.05.1994")
And this is the error I am getting:
Traceback (most recent call last):
File "dec_new.py", line 22, in <module>
search("Dibenzoylperoxid")
File "dec_new.py", line 14, in search
s+=struct.pack("b", ord(c))
TypeError: Can't convert 'bytes' object to str implicitly
Kindly, let me know what I can do to make it functional properly.
I am using Python 3.5.0.
s = ""
for c in text:
s+=struct.pack("b", ord(c))
This won't work because s is a string, and struct.pack returns a bytes, and you can't add a string and a bytes.
One possible solution is to make s a bytes.
s = b""
... But it seems like a lot of work to convert a string to a bytes this way. Why not just use encode()?
def search(text):
#convert the text to binary first
s = text.encode()
results = binary_data.find(s)
#etc
Also, "your binary data would show up as a big string like this one when you .read()" is not, strictly speaking, true. The binary data won't show up as a big string, because it is a bytes, not a string. If you want to create a bytes literal that resembles what might be returned by open("your_binary_file.bin","rb").read(), use the bytes literal syntax binary_data = b'\x44\x69<...etc...>\x33\x30'
It gives me an error that the line encoded needs to be bytes not str/dict
I know of adding a "b" before the text will solve that and print the encoded thing.
import base64
s = base64.b64encode(b'12345')
print(s)
>>b'MTIzNDU='
But how do I encode a variable?
such as
import base64
s = "12345"
s2 = base64.b64encode(s)
print(s2)
It gives me an error with the b added and without. I don't understand
I'm also trying to encode/decode a dictionary with base64.
You need to encode the unicode string. If it's just normal characters, you can use ASCII. If it might have other characters in it, or just for general safety, you probably want utf-8.
>>> import base64
>>> s = "12345"
>>> s2 = base64.b64encode(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ". . . /lib/python3.3/base64.py", line 58, in b64encode
raise TypeError("expected bytes, not %s" % s.__class__.__name__)
TypeError: expected bytes, not str
>>> s2 = base64.b64encode(s.encode('ascii'))
>>> print(s2)
b'MTIzNDU='
>>>
I would like to add hexvalues to a binary string so that I end up with a binary string that can be transmitted.
What I want is:
StringToAppend = "5ce7e615ff0000000000010202041f0140009e005d006404084c5ce82215ff1d02000000010202041f013b0097005c005e04777c" (I have this in unhexlified form and want to append it to a string a la StatusStr = chr(0)
How do I do this??? This is what i have:
>>> not_macs_buffer= unhexlify("5ce7e615ff0000000000010202041f0140009e005d006404084c5ce82215ff1d02000000010202041 f013b0097005c005e04777c")
>>> StatusStr = chr(0)
>>> for i in xrange(0,len(not_macs_buffer)):
... StatusStr +=chr(not_macs_buffer[i])
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: an integer is required
>>>
What are you transmitting the string to/from? Does it have to be in hex?
The issue seems to be that are you are converting your hex string into a binary string, then in your loop you are attempting to convert a string character into a character, using chr(). This fails because chr() only takes an integer value representing a 256-value ASCII code, not a string.
To fix your problem, just change StatusStr +=chr(not_macs_buffer[i]) to this:
StatusStr += not_macs_buffer[i]
Of course, you could forgo the loop completely.
StatusStr = chr(0) + not_macs_buffer
And if you really did need to convert a list of integers to a string, you could use a list comprehension and then join the list. (I won't give an example since it's not relevant)
EDIT:
If you want to add the null value to your original hex string, you can do this:
StringToAppend = '5ce7e6' # ... snip the real value
StatusStr = hexlify(chr(0)) + StringToAppend
# or
StatusStr = hexlify('\x00') + StringToAppend
# or
StatusStr = '0000' + StringToAppend
Well, Thanks all but what I actually ended up doing to get what I wanted, is:
>>> not_macs_buffer= unhexlify("5ce7e615ff0000000000010202041f0140009e005d006404084c5ce82215ff1d02000000010202041 f013b0097005c005e04777c")
>>> StatusStr = chr(0)
>>> for i in xrange(0,len(not_macs_buffer)):
... StatusStr +=chr(ord(not_macs_buffer[i]))