Question

I have a socket server listening for UDP packets from a GSM device. Some of the data comes in as multibytes, such as time, which requires multibytes for accuracy. This is an example:

179,248,164,14

The bytes are represented in decimal notation. My goal is to convert that into seconds:

245692595

I am trying to do that and was told:

"You must take those 4 bytes and place them into a single long integer in little endian format. If you are using Python to read and encode the data, you will need to look at using the .read() and struct.unpack() methods to successfully convert it to an integer. The resulting value is the number of seconds since 01/01/2000."

So, I tried to do this:

%w(179 248 164 14).sort.map(&:to_i).inject(&:+)
 => 605 

And I obviously am getting the wrong answer.

Was it helpful?

Solution

You should use the pack and unpack methods to do this:

[179,248,164,14].pack('C*').unpack('I')[0]
# => 245692595

It's not about adding them together, though. You're doing the math wrong. The correct way to do it with inject is this:

 [179,248,164,14].reverse.inject { |s,v| s * 256 + v }
 # => 245692595

Note you will have to account for byte ordering when representing binary numbers that are more than one byte long.

If the original data is already a binary string you won't have to perform the pack operation and can proceed directly to the unpack phase.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top