Raspberry Pi - How to print hex value? - python

I m using Python in Raspberry Pi and my packet is in hexadecimal value like "0x750x010x010x060x000x08". I want serial communication between UART and Raspberry Pi so I wrote a program using Python in Raspberry Pi and I'm checking data on terminal but when I selected ASCII option in terminal it showing below output:
75
01
01
06
00
08
And when I selected hex option in terminal it is not showing above output. Now I want above output when I will select hex option but not ASCII option. So how to get that? If I need to convert it into hex or byte or any other than tell me the code in Python.

import serial
port=serial.Serial("/dev/ttyAMA0",baudrate=115200,timeout=3.0)
while True:
a="0x750x010x010x060x000x08"
b=a.replace("0x"," ")
#print b
alist = b.split(" ")
for element in alist
port.write("\r\n"+str(element))
this gives the desired formatted data you want

First of all your for loop and if statment are used wrong here, and they are not required. The while loop can be equivently rewriten as:
a = "0x750x010x010x060x000x08"
b = a.replace("0x", " ")
while True:
port.write("\r\n"+b)
Your main misanderstanding is that you assume Python understands you want to iterate over hex numbers. But it doesn't. In you original loop it just iterates the a string letter by letter. And in fact at each iteration of for loop you just changes the orignal a string to " 75 01 01 06 00 08" and send it as a string.
If you need to send bytes, you should split your string into separate records with each byte's infromation and convert these records to bytes.
Here is the code for that
a = "0x750x010x010x060x000x08"
b1 = a.split("0x")
# b1 is ["", "75", "01", "01", "06", "00", "08"], the values are still strings
b2 = [int(x, 16) for x in b1[1:]]
# b2 is a list of integers, the values calculated from strings assuming they are hex (16-bit) numbers
# use b1[1:] to cut the first blank string
b = str(bytearray(b2))
#b joins values list into a bytes string (each interger transformed into one byte)
while True:
port.write("\r\n" + b)
Update for question in comments:
If a format is like this "0x750101060008", you just split it by 2 letters:
b1 = [a[2*i:2*i+2] for i in range(len(a)/2)]

import serial
port=serial.Serial("/dev/ttyAMA0",baudrate=115200,timeout=3.0)
while True:
a="0x750x010x010x060x000x08"
b=a.replace("0x"," ")
#print b
alist = b.split(" ")
for element in alist
port.write("\r\n"+str(element))
this one

Related

How to convert Binary to Strings?

I am currently working on a binary encryption code: [Sender(Msg Input=> Binary Conversion)] : [Receiver (Binary Conversion => Msg Output)]
As of now I am able to convert text based Msgs , e.g) How are you? etc.
print("Enter Msg:")
def Binary_Encryption(message):
message = ''.join(format(i, 'b') for i in bytearray(message, encoding ='utf-8'))
print(message)
Binary_Encryption(input("").replace (" ","\\"))
Output: 10010001101111111011110111001100001111001011001011011100111100111011111110101111111
After the binary string is obtained, by just copying the string and placing it within this block of code will decrypt it.
def Binary_Decryption(binary):
string = int(binary, 2)
return string
bin_data = (input("Enter Binary:\n"))
str_data =''
for i in range(0, len(bin_data), 7):
temp_data = bin_data[i:i + 7]
decimal_data = Binary_Decryption(temp_data)
str_data = str_data + chr(decimal_data)
print("Decrypted Text:\n"+str_data.replace("\\"," "))
Output: How are you?
But I am not able to convert a certain inputs , e.g) ?? , 8879 , Oh! How are You? etc.
basically the msgs that are not being converted are Msgs with multiple uses of numbers or special
characters.
Msg Input for ?? gives "⌂▼" and 8879 gives "qc?☺" while Oh! How are You? gives "OhC9◄_o9CeK93_k▼
I think the problem is that the special characters (!, ?) contains only 6 bits, while the other characters 7.This messes things up if there are other characters behind the special one I think. Maybe something like this should work. There is probably a better way to solve this though.
def Binary_Encryption(message):
s = ""
for i in bytearray(message, encoding="utf-8"):
c = format(i, "b")
addon = 7 - len(c)
c = addon * "0" + c # prepend 0 if len shorter than 7
s += c # Add to string
print(s)
Your problem is that you are copying the output from binary_encrypt directly which truncate leading zeros so 8 instead of being 00111000 it became 111000 which result in 2 bits being used from next ASCII binary character since ASCII characters are represented as 8-bits values to print number 8897 use0011100000111000001110010011011100001010 as input to binary_decrypt. look for ASCII table to see the binary equivalents for each character.Just edit your code like this.
print("Enter Msg:")
def Binary_Encryption(message):
# pass 08b to format
message = ''.join(format(i, '08b') for i in bytearray(message, encoding ='utf-8'))
print(message)
Binary_Encryption(input("").replace (" ","\\"))

Python Print Hex variable

I have hex variable that I want to print as hex
data = '\x99\x02'
print (data)
Result is: ™
I want to the python to print 0x9902
Thank you for your help
Please check this one.
data = r'\x99\x02'
a, b = [ x for x in data.split(r'\x') if x]
d = int(a+b, base=16)
print('%#x'%d)
You have to convert every char to its number - ord(char) - and convert every number to hex value - '{:02x}'.format() - and concatenate these values to string. And add string '0x'.
data = '\x99\x02'
print('0x' + ''.join('{:02x}'.format(ord(char)) for char in data))
EDIT: The same but first string is converted to bytes using encode('raw_unicode_escape')
data = '\x99\x02'
print('0x' + ''.join('{:02x}'.format(code) for code in data.encode('raw_unicode_escape')))
and if you have already bytes then you don't have to encode()
data = b'\x99\x02'
print('0x' + ''.join('{:02x}'.format(code) for code in data))
BTW: Similar way you can convert to binary using {:08b}
data = '\x99\x02'
print(''.join('{:08b}'.format(code) for code in data.encode('raw_unicode_escape')))

How to read double, float and int values from binary files in python?

I have a binary file that was created in C++. The first value is double and the second is integer. I am reading the values fine using the following code in C++.
double dob_value;
int integer_value;
fread(&dob_value, sizeof(dob_value), 1, fp);
fread(&integer_value, sizeof(integer_value), 1, fp);
I am trying to read the same file in python but I am running into issues. My dob_value is 400000000.00 and my integer_value 400000. I am using following code in python for double.
def interpret_float(x):
return struct.unpack('d',x[4:]+x[:4])
with open(file_name, 'rb') as readfile:
dob = readfile.read(8)
dob_value = interpret_float(dob)[0]
val = readfile.read(4)
test2 = readfile.read(4)
integer_value = int.from_bytes(test2, "little")
My dob_value is 400000000.02384186 . My question is where is this extra decimals coming from? Also, how do I get the correct integer_value? With above code, my integer_value is 1091122467. I also have float values after integer but I haven't looked into that yet.
If the link goes broken and just in case the test.bin contains 00 00 00 00 84 D7 B7 41 80 1A 06 00 70 85 69 C0.
Your binary contains correct 41B7D78400000000 hexadecimal representation of 400000000.0 in the first 8 bytes. Running
import binascii
import struct
fname = r'test.bin'
with open(fname, 'rb') as readfile:
dob = readfile.read(8)
print(struct.unpack('d', dob)[0])
print(binascii.hexlify(dob))
outputs
>> 400000000.0
>> b'0000000084d7b741'
which is also correct little endian representation of the double. When you swap parts, you get
print(binascii.hexlify(dob[4:]+dob[:4]))
>> b'84d7b74100000000'
and if you check the decimal value, it will give you 5.45e-315, not what you expect. Moreover,
struct.unpack('d', dob[4:]+dob[:4])[0]
>>5.44740625e-315
So I'm not sure how you could get 400000000.02384186 from the code above. However, to obtain 400000000.02384186 using your test.bin, just skip the four bytes in the beginning:
with open(fname, 'rb') as readfile:
val = readfile.read(4)
dob = readfile.read(8)
dob = dob[4:]+dob[:4]
print(binascii.hexlify(dob))
print(struct.unpack('d', dob)[0])
>>b'801a060084d7b741'
>>400000000.02384186
Binary value 0x41B7D78400061A80 corresponds to 400000000.02384186. So you first read incorrect bytes, then incorrectly swap parts and get a result close to what you expect. Considering integer value, the 400000 is 0x00061A80, which is also present in the binary, but you definitely read past that bytes, since you used them for double, so you get wrong values.

How do I force recv() in Socket to NOT convert my hex values into ASCII if it can (python)

I am using python 3.4 socket interface of python-can. I am having a problem, when I receive the data via recv() or recvfrom() it converts some of the hex data in the message to ASCII if it can for example '63' becomes a 'c'. I do not want this, I want the raw hex data.
Here is a snippet part of the code:
def dissect_can_frame(frame):
can_id, can_dlc, data = struct.unpack(can_frame_fmt, frame)
global dataS
dataS = data[:can_dlc]
return (can_id, can_dlc, data[:can_dlc])
s = socket.socket(socket.AF_CAN,socket.SOCK_RAW,socket.CAN_RAW)
print(s)
s.bind((can_interface,))
#s.bind((sys.argv[1],)) #used for 'can0' as argument at initial execution
print(socket.AF_CAN,",",socket.SOCK_RAW,",",socket.CAN_RAW)
#while True:
cf, addr = s.recvfrom(4096)
print(cf,',',addr)
I get "b'\x18c\xd8\xd6\x1f\x01 \x18'" as the output section of the data instead of "18 63 D8 D6 1F 01 20 18". Do not care about the formatting but notice how '63' has become 'c' and '20' has inserted a space. Can I stop it doing this?
Is it common for socket to convert the data rather than producing the raw data?
Thank you for any help.
That's just how the data looks when it comes out of recv. If you want to convert it into a hex-looking string, then you can use format on each character:
>>> s = b'\x18c\xd8\xd6\x1f\x01 \x18'
>>> " ".join(["{:02X}".format(ord(c)) for c in s])
'18 63 D8 D6 1F 01 20 18'
Of course, this is an inconvenient format for actually doing any kind of analysis on the data. But it looks nice for display purposes.
Alternatively, there's hexlify, but that doesn't space out the values for you:
>>> import binascii
>>> binascii.hexlify(s)
'1863d8d61f012018'

Python RSA Decrypt for class using vs2013

For my class assignment we need to decrypt a message that used RSA Encryption. We were given code that should help us with the decryption, but its not helping.
def block_decode(x):
output = ""
i = BLOCK_SIZE+1
while i > 0:
b1 = int(pow(95,i-1))
y = int(x/b1)
i = i - 1
x = x - y*b1
output = output + chr(y+32)
return output
I'm not great with python yet but it looks like it is doing something one character at a time. What really has me stuck is the data we were given. Can't figure out where or how to store it or if it is really decrypted data using RSA. below are just 3 lines of 38 lines some lines have ' or " or even multiple.
FWfk ?0oQ!#|eO Wgny 1>a^ 80*^!(l{4! 3lL qj'b!.9#'!/s2_
!BH+V YFKq _#:X &?A8 j_p< 7\[0 la.[ a%}b E`3# d3N? ;%FW
KyYM!"4Tz yuok J;b^!,V4) \JkT .E[i i-y* O~$? o*1u d3N?
How do I get this into a string list?
You are looking for the function ord which is a built-in function that
Returns the integer ordinal of a one-character string.
So for instance, you can do:
my_file = open("file_containing_encrypted_message")
data = my_file.read()
to read in the encrypted contents.
Then, you can iterate over each character doing
char_val = ord(each_character)
block_decode(char_val)

Categories

Resources