0

I need an application that will do the following:

  1. read UDP message, get data from it - the data is textual, comma separated.
  2. build a new message based on this values
  3. send a new UDP message to other destination.

For the first and the last I'm fine. for the second I have a challenge: Lets say that the data I've received is Year = 2020. The message on the Wireshark (step 3), I shall see it as 2 bytes valued 07 e4

How can I do it? I've tried couple of ways, none of them provided me with the desired format.

Sample of the code:

data1 = '\xab\xcd\xef\xgh'
...
data, addr = sock.recvfrom (200)
elements = data.decode().split(",")
Date=elements[15].split("/")
Year = int(Date(2))
year = <do something with Year to convert to right format>
newMsg = data1 + year
...
newSock.sendto(newMsg.encode('charmap'), (IP, int(port)))

Python version 3.5

user1977050
  • 496
  • 1
  • 6
  • 18
  • Does this answer your question? https://stackoverflow.com/questions/2269827/how-to-convert-an-int-to-a-hex-string – go2nirvana Nov 02 '20 at 13:50
  • 1
    have a look at [struct](https://docs.python.org/3.9/library/struct.html), it offers useful functionality for these kinds of message composing, e.g. `struct.pack('!h', 2020)` – FObersteiner Nov 02 '20 at 14:00
  • @go2nirvana - no. the assumption there is that the integer is less than 255. I need values greater than that – user1977050 Nov 02 '20 at 14:04
  • @MrFuppes, as mentioned, the original value is textual, comma separated, which includes day and time (aa:bb:cc.dd, XX/YY/ZZ) - I need to extract each of those values and rebuild a new packet, which contains additional data. this data is stored as string – user1977050 Nov 02 '20 at 14:07
  • @user1977050 there is no such assumption. You can use `hex` to convert any integer to hexadecimal. – go2nirvana Nov 02 '20 at 14:09
  • I've updated the post with some sample of the code so that it will be more clear what I'm doing. – user1977050 Nov 02 '20 at 14:14
  • if you encode `newMsg` to charmap in the end, I think you should be working with strings beforehand, not bytes. But that would make `'2020'` 4 bytes, not two. – FObersteiner Nov 02 '20 at 14:27
  • @MrFuppes therefore I'm looking for a solution to my issue. Maybe I shall do something else at all – user1977050 Nov 02 '20 at 14:33

1 Answers1

1

there seem to be a couple of issues here. first, if your data1 is really supposed to be raw bytes then you're better off declaring it as such by prefixing it with a b, something like:

data1 = b'\xab\xcd\xef\xff'

if it comes from somewhere else, then encode it to bytes appropriately.

for answering your main question, the struct module has useful tools for encoding numbers as bytes in the way you want. ctypes can also be useful, but struct tends to be easier to use for these sorts of things:

data, addr = sock.recvfrom (200)
elements = data.decode().split(",")
date = elements[15].split("/")
year = int(date(2))
newMsg = data1 + struct.pack('!h', year)

and then you can send it with:

newSock.sendto(newMsg, (IP, int(port)))
Sam Mason
  • 15,216
  • 1
  • 41
  • 60
  • 2 questions: A. I have additional variable called `Month`. when I try to perform a pack, it appends 2 bytes instead of single. How do solve it? B. I need to calculate checksum on the message. I've tried `sum (newMsg)` but it expects int type – user1977050 Nov 03 '20 at 06:02
  • a. read the docs of [struct](https://docs.python.org/3/library/struct.html) to see how to pack a byte. b. checksums are a large subject of their own, mostly unrelated to numerical summation. I'd suggest searching for existing code that does something similar – Sam Mason Nov 03 '20 at 08:47
  • a. just solved it. b. - previously I had `s=0` `for k in newMsg:` `sum+=ord(k)` to what shall I change it now? – user1977050 Nov 03 '20 at 09:00
  • `list(b'abc')` evaluates to the same as `[ord(k) for k in 'abc']` – Sam Mason Nov 03 '20 at 09:14