Moderated Discussion Areas
ContinuousWave: Small Boat Electrical
Decoding AIS Messages
|Author||Topic: Decoding AIS Messages|
posted 12-29-2011 10:35 AM ET (US)
Being technically curious, I have been looking into the method used to encode and decode data sent in AIS messages. There is a wonderful resource that explains the method that is available from:
Using that information as a guide, I set about to decode a random AIS message I had received. Here is the raw AIS message:
The message is not particularly human-readable, and it must be carefully decoded to extract the data. Here is my attempt to decode, which will by example demonstrate the method.
The message has seven fields. The first five fields are easily decoded by simple inspection. The sixth field is the data payload and requires rather complicated decoding: Using my sample message as an example, we find:
FIELD DATA INTERPRETATION
With fairly simple inspection we know this is an AIS message, it is in one fragment, this is the first fragment, it is not part of a longer message sequence, and it was sent on radio channel 161.975-MHz. Now for the hard part: decoding the data paylod.
Decoding the data payload
The data payload is a complicated encoding of information into ASCII strings. Each ASCII character represents six bits of data. We explain by example. Consider the first ASCII character in the payload, "1":
ASCII character "1" is ASCII value 49. To recover the data payload we subtract 48 from this value. If the result is greater than 40, subtract 8.
49 - 48 = 1
Our data payload is decimal 1. Decimal 1 is a six-bit binary number 000001.
The first six bits of our data payload are 000001. They are the message type. A message type of "000001" decodes to "Position Report Class A."
The next ASCII character is "5". This decodes to "110101"
ASCII BINARY PAYLOAD
Now we concatenate all the decoded payloads into one long message string. This string is then decoded as follows
BIT POSITION DATA OUR DATA MEANING
Now we can decode the data that follows according to the format for Position Report Class A, which is:
6-7 Repeat Indicator 00
The data in position 8 through 37 represents the unsigned binary number which is the binary equivalent of a 9-digit decimal number--the vessel MMSI:
1 5 O 8 6 n 0 0 1 RAW DATA
The MMSI of the vessel sending this packet is 368183000.
Field 38 through 41 (four bits) encodes the Navigation status as an enumerated type. With four bits there are 16 enumerated types. Our message payload is
1 5 O 8 6 n 0 0 1 RAW DATA
which interprets to "Underway using engine."
Field 42 through 49 are eight bits which encode the Rate of Turn.
1 5 O 8 6 n 0 0 1 RAW DATA
The data payload for Rate of Turn in this case is 00000000 or "not turning."
Now we get more of the data payload for the next encoded data.
1 T J 3 K u t 8 a r RAW DATA
Field 50 to 59 encode the Speed Over Ground. Our data payload is
which is a binary number that converts to decimal 100. Speed is given to the tenth of a knot, so the vessel speed is 10.0-knots.
posted 12-29-2011 11:01 AM ET (US)
So far I have been able to successfully decode the data from the message, but on the longitude field, I have been stumped. I need some help.
Field 61 through 88 encodes the longitude.
1 T J 3 K u t 8 a r
The data payload is 1101000001101101111110111110.
"Numeric bitfields are interpreted as big-endian two's-complement integers; when signed, the sign bit is the highest."
The first bit is the sign: 0 means positive and 1 means negative. This is a negative number, hence a longitude west of the prime meridian. The value of the negative number is
We decode this as 84336574. Is that correct?
The data "84336574" is supposed to represent the longitude in units of 0.0001-minutes. The actual longitude being transmitted is 083.135250-West. I know this because I used an automated decoder to process the message.
The longitude 083.135250 would be converted to the necessary units as follows:
083.135250-degrees x 60-minutes/1-degree = 4988.115-minutes
4988.115-minutes x (10,000) =49,881,150--10,000ths of a minute
and this implies the AIS ought to be transmitting a number "49881150"
I cannot figure out where I have gone off the tracks here. There are three possibilities:
--I extracted the wrong binary data from the payload;
--I converted the binary payload data to decimal incorrectly; or,
--I converted to the decimal data to longitude incorrectly.
I seek some assistance here. Perhaps someone can check my steps with the longitude data and discover the error. I suspect it is likely in the conversion of the binary data to decimal. See the linked reference for more details about the representation of signed numbers in binary. Thanks for any light you can shine on this for me.
posted 12-29-2011 11:26 AM ET (US)
I found a very handy on-line binary<-->decimal converter at
Using this device, I convert my decoded payload binary to decimal as follows:
BINARY = 101000001101101111110111110
DECIMAL = 84336574
That is the same number I got, so my conversion must be correct. This means the error must be in:
--bad decoding of data payload to binary
--bad conversion of decimal to longitude
Again, I seek some assistance, as I have checked those steps myself already.
posted 12-29-2011 11:57 AM ET (US)
Using two's complement arithmetic, the number being represented is actually -49881154.
posted 12-29-2011 12:10 PM ET (US)
Let's try Dave's number:
As a negative, this means West longitude. The number represents the number of 10,000th-of-a-minute. It is also sent as an integer and needs to scaled to four decimal places, thus
Divide by 60 to get degrees:
4988.1154 / 60 =83.135256666666667-degrees
The indicated position was supposed to be
and this value (-49881154) decodes to
The difference appears to be due to truncating instead of rounding. Perhaps that is an error in the other convertor.
Now, Dave, please explain to me the method you used to decode
into -49881154. I don't quite understand the two's-complement aspect you mention.
posted 12-29-2011 12:23 PM ET (US)
Wait--I have it:
The method is as follows:
Take the decoded binary number from the AIS payload, strip off the first bit as a sign, then take the remaining bits as an unsigned integer that is the two's complement of the actual number. Convert the original data to its two's complement.
The first bit of the payload was a "1" hence a negative number. The remaining payload becomes:
We apply the method:
Now we convert the new binary number to decimal as an unsigned integer:
010111110010010000001000010 --> 49881154
posted 12-29-2011 01:11 PM ET (US)
Yes, that's it.
There are 11 types of people that understand binary, those that do and those that do not. :)
posted 12-29-2011 01:13 PM ET (US)
And leave it to me to screw up a bad pun...
posted 12-29-2011 01:56 PM ET (US)
There are two secrets to success: the first, don't share everything you know.
posted 12-29-2011 02:55 PM ET (US)
I tried entering the decoded binary in the convertor (linked above) but it never produced the right decimal. I think that was because the convertor need me to pad out the number to 32-bits. If I took my original data, padded the most-significant bits with "1" to fill out to 32-bits, the convertor worked correctly.
I believe this is called "sign extension," as discussed at
The original number was 28-bits. The convertor wanted a 32-bit number, so it needed to be padded with "1' on the MSB side to 32 bits. Confusing stuff, this binary arithmetic.
ASIDE: re Dave's joke, see
posted 12-29-2011 03:24 PM ET (US)
Well, now that I have demonstrated the method, we'll leave decoding of the latitude as an exercise for the reader. That's about all I remember from my last text in mathematics.
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.