Backporting bytearray to Python 2.5 - python

I'm trying to convert this websocket example for use in Python 2.5, but am running into errors with the use of the bytearray type.
The code stops working for Python 2.5 here (in the send_text method of websocket_server/websocket_server.py):
FIN = 0x80
OPCODE = 0x0f
def send_text(self, message):
header = bytearray();
payload = encode_to_UTF8(message)
payload_length = len(payload)
header.append(FIN | OPCODE_TEXT)
header.append(payload_length)
self.request.send(header + payload)
The message variable stores the string input that is sent to clients.
It attempts to create an array of bytes and send that using the self.request.send method. How would I change this to make it work in Python 2.5 which doesn't have the bytes type or bytearray?

Using struct MIGHT work, I haven't tested this.
What I would do, as a workaround, would be to use struct.pack to pack byte by byte.
mensaje = "saludo"
FIN = 0x80
OPCODE = 0x0f
payload = ''
for c in mensaje:
payload += struct.pack("H", ord(c))
msj = struct.pack("H",FIN | OPCODE )
msj+= struct.pack("H",len(payload))
print msj + payload
I'm using "H" as the 'fmt' parameter in the struct.pack function, but you better check how is your package sent and how many bytes per 'character' (since I'm guessing you're using unicode, I'm using 'H', unsigned short = 2 bytes).
More info: https://docs.python.org/2/library/struct.html, section 7.3.2.1 and 7.3.2.2.
EDIT:
I'll answer here, what do I mean by using 'chr()' instead of 'struct.pack()':
mensaje = "saludo"
FIN = 0x80
OPCODE = 0x0f
payload = mensaje
msj = chr( FIN | OPCODE )
msj+= chr(len(payload))
print msj + payload
if you print the message, then you should see the same output when using struct.pack("B", ord(something)) than when using ord(something), I just used struct.pack() because I thought your message was two bytes per char (as unicode).

Related

split python bytearray character by character

So, I've got some python code
string = "Python is interesting."
arr = bytearray(string, 'utf-8')
arr.split(b'\'')
which I adapted from Split String by char Character
but it returns a
[bytearray(b'Python is interesting.')]
I was hoping to split it byte-by-byte. The end goal is to pass this to a C++ boost wrapper which expects an array of bytes character-by-character. I'm using a bytearray because I'm actually working with sockets and for a given large message I want to accumulate them.
expected_length = _get_obj_size(socket)
running_length = 0
accumulator = bytearray(b'')
while running_length < expected_length:
msg = socket.recv(BUFFER_SIZE)
if msg:
running_length += len(msg)
accumulator += msg
logger.debug("Finished reading in payload")
^ the above isn't particularly relevant but I felt like it might be useful to show why I'm doing what I'm doing.
Taking the hint from #Epsi95 what about:
[chr(x) for x in list(arr)]

Send UDP Datagrams using Python

I want to send a data request over udp using the socket API. The format of the request is as follows:
ID | Data_Length | Data
The request contains the following parameters :An Identifier (ID), (Data_Length) is the size of (Data) and (Data) which is the data to be sent, (Data) has a variable size.
The code I wrote is as follows:
def send_request():
request_format="bbs" # 1 Byte for the ID 1 Byte for Data_Length and s for data
data_buff=np.array([1,2,3,4,5,6,7,8,9]) # Data to be sent
msg = struct.pack(request_format,0x01,0x09,data_buff.tobytes())
print("msg = ", msg)
s0.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s0.sendto(msg, (UDP_BC_IP, UDP_SERVER_PORT))
My questions:
1- Using Wireshark I can see that only the 1st Byte of Data has been sent why ?
2- The output of the print instruction is msg = b'\x01\t\x01' why did I get this output, I was waiting for something similar to [0x01,0x09,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09]
Check the dtype of data_buff - it is int64 unless you use:
data_buff = np.array([1,2,3,4,5,6,7,8,9], dtype=np.uint8)
Then repeat your s specifier according to the size of the array:
request_format="bb" + str(data_buff.size) + "s"
Now you can pack with:
msg = struct.pack(request_format,0x01,0x09,data_buff.tobytes())
and your message will look like this:
b'\x01\t\x01\x02\x03\x04\x05\x06\x07\x08\t'
The TAB character is ASCII code 9, so you will see \t where your data is 9.

Python adds extra to crypt result

I'm trying to create an API with token to communicate between an Raspberry Pi and a Webserver. Right now i'm tring to generate an Token with Python.
from Crypto.Cipher import AES
import base64
import os
import time
import datetime
import requests
BLOCK_SIZE = 32
BLOCK_SZ = 14
#!/usr/bin/python
salt = "123456789123" # Zorg dat de salt altijd even lang is! (12 Chars)
iv = "1234567891234567" # Zorg dat de salt altijd even lang is! (16 Chars)
currentDate = time.strftime("%d%m%Y")
currentTime = time.strftime("%H%M")
PADDING = '{'
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
secret = salt + currentTime
cipher=AES.new(key=secret,mode=AES.MODE_CBC,IV=iv)
encode = currentDate
encoded = EncodeAES(cipher, encode)
print (encoded)
The problem is that the output of the script an exta b' adds to every encoded string.. And on every end a '
C:\Python36-32>python.exe encrypt.py
b'Qge6lbC+SulFgTk/7TZ0TKHUP0SFS8G+nd5un4iv9iI='
C:\Python36-32>python.exe encrypt.py
b'DTcotcaU98QkRxCzRR01hh4yqqyC92u4oAuf0bSrQZQ='
Hopefully someone can explain what went wrong.
FIXED!
I was able to fix it to decode it to utf-8 format.
sendtoken = encoded.decode('utf-8')
You are running Python 3.6, which uses Unicode (UTF-8) for string literals. I expect that the EncodeAES() function returns an ASCII string, which Python is indicating is a bytestring rather than a Unicode string by prepending the b to the string literal it prints.
You could strip the b out of the output post-Python, or you could print(str(encoded)), which should give you the same characters, since ASCII is valid UTF-8.
EDIT:
What you need to do is decode the bytestring into UTF-8, as mentioned in the answer and in a comment above. I was wrong about str() doing the conversion for you, you need to call decode('UTF-8') on the bytestring you wish to print. That converts the string into the internal UTF-8 representation, which then prints correctly.

Google OAuth in Python 3 error

I followed this awesome answer for implementing Google OAuth in Python. However, when I tried running in Python 3, I get this error:
TypeError: ord() expected string of length 1, but int found
This error is thrown by this line:
o = ord(h[19]) & 15
Trying o = ord(str(h[19])) & 15 resulted in:
TypeError: ord() expected a character, but string of length 3 found
This happens in Python 3, but not in Python 2, which makes me think that some types have changed between versions. This is the relevant code:
def get_hotp_token(secret, intervals_no):
key = base64.b32decode(secret)
msg = struct.pack(">Q", intervals_no)
h = hmac.new(key, msg, hashlib.sha1).digest()
o = ord(h[19]) & 15
h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
return h
I tried to follow this question's answers, but they did not help. The first answer did not help because I am not using a string literal for key or msg. This was my attempt at implementing the second answer's suggestion:
def get_hotp_token(secret, intervals_no):
key = base64.b32decode(secret)
key_bytes = bytes(key, 'latin-1')
msg = struct.pack(">Q", intervals_no)
msg_bytes = bytes(msg, 'latin-1')
h = hmac.new(key_bytes, msg_bytes, hashlib.sha1).digest()
o = ord(h[19]) & 15
h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
return h
This code threw this error on the key_bytes = <...> and msg_bytes = <...>:
TypeError: encoding without a string argument
Using utf-8 instead of latin-1 had the same result.
If I print(key, msg), I get this, which suggests that they are already in a byte-like form:
b'fooooooo37' b'\x00\x00\x00\x00\x02\xfa\x93\x1e'
The msg printed explains the ... string of length 3 found error above.
I am unsure where to go from here. Any suggestions/solutions would be great!
hmac.new() returns a string of bytes. In Python 3 this is an array of integers. Hence h[19] is an integer. Just use that int instead of calling ord(). Or decode h to str.

File is not decoded properly

I have a file encoded in a strange pattern. For example,
Char (1 byte) | Integer (4 bytes) | Double (8 bytes) | etc...
So far, I wrote the code below, but I have not been able to figure out why still shows garbage in the screen. Any help will be greatly appreciated.
BRK_File = 'commands.BRK'
input = open(BRK_File, "rb")
rev = input.read(1)
filesize = input.read(4)
highpoint = input.read(8)
which = input.read(1)
print 'Revision: ', rev
print 'File size: ', filesize
print 'High point: ', highpoint
print 'Which: ', which
while True
opcode = input.read(1)
print 'Opcode: ', opcode
if opcode = 120:
break
elif
#other opcodes
read() returns a string, which you need to decode to get the binary data. You could use the struct module to do the decoding.
Something along the following lines should do the trick:
import struct
...
fmt = 'cid' # char, int, double
data = input.read(struct.calcsize(fmt))
rev, filesize, highpoint = struct.unpack(fmt, data)
You may have to deal with endianness issues, but struct makes that pretty easy.
It would be helpful to show the contents of the file, as well as the "garbage" that it's outputting.
input.read() returns a string, so you have to convert what you're reading to the type that you want. I suggest looking into the struct module.

Categories