13

I have a FixMessage and I want to calculate the checksum manually.

8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|10=157|

The body length here is calculated:

8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|10=157|
0        + 0  + 5  + 5  + 8     + 26                     + 5   + 0  = 49(correct)

The checksum is 157 (10=157). How to calculate it in this case?

TT.
  • 15,774
  • 6
  • 47
  • 88
anhtv13
  • 1,636
  • 4
  • 30
  • 51

5 Answers5

10

You need to sum every byte in the message up to but not including the checksum field. Then take this number modulo 256, and print it as a number of 3 characters with leading zeroes (e.g. checksum=13 would become 013).

Link from the FIX wiki: FIX checksum

An example implementation in C, taken from onixs.biz:

char *GenerateCheckSum( char *buf, long bufLen )
{
    static char tmpBuf[ 4 ];
    long idx;
    unsigned int cks;

    for( idx = 0L, cks = 0; idx < bufLen; cks += (unsigned int)buf[ idx++ ] );
    sprintf( tmpBuf, "%03d", (unsigned int)( cks % 256 ) );
    return( tmpBuf );   
}
TT.
  • 15,774
  • 6
  • 47
  • 88
  • "sum every byte in the message". Can you write it in this case? – anhtv13 Sep 22 '15 at 09:25
  • I still dont understand that example. I write c#. If I have a FixMessage: {8=FIX.4.29=4935=534=149=ARCA52=20150916-04:14:05.30656=TW10=157}. How to count it to 157? – anhtv13 Sep 23 '15 at 11:03
  • @ANguyen Quickfix is a library that can produce a FIX message for you. A FIX message is a string consisting of [ASCII characters](https://en.wikipedia.org/wiki/ASCII). To calculate the checksum, 1/ each byte in the message up to the checksum field is summed 2/ take the modulo 256 of that sum 3/ print that number as a number of 3 characters with leading zeros. I can't say it simpler that that. You can't simply dump a FIX message here and expect us to count it for you. You ask the QuickFIX library or any other FIX engine to do it for you. – TT. Sep 23 '15 at 11:18
  • @ANguyen For me it's been too long since I've done any C# coding, and I'm not proficient with QuickFIX/N. Look into converting a string to a byte stream or byte-array (ASCII encoding). Sum each byte in the array or stream to an unsigned int. Then take the modulo 256 of the total and print it as a 3 character string with leading zeroes. – TT. Sep 23 '15 at 11:26
  • When I compile that example C program and use the wiki page test case, it gives me 70, not 65 as wiki says – fersarr Apr 21 '16 at 15:44
  • @fersarr Did you replace the pipe symbols (`|`) in the example by the SOH character (ASCII code 0x01)? – TT. Apr 21 '16 at 16:55
5

Ready-to-run C example adapted from here

8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|10=157|

#include <stdio.h>

void GenerateCheckSum( char *buf, long bufLen )
{
        unsigned sum = 0;
        long i;
        for( i = 0L; i < bufLen; i++ )
        {
            unsigned val = (unsigned)buf[i];
            sum += val;
            printf("Char: %02c Val: %3u\n", buf[i], val); // print value of each byte
        }
        printf("CheckSum = %03d\n", (unsigned)( sum % 256 ) ); // print result
}

int main()
{
    char msg[] = "8=FIX.4.2\0019=49\00135=5\00134=1\00149=ARCA\00152=20150916-04:14:05.306\00156=TW\001";
    int len = sizeof(msg) / sizeof(msg[0]);
    GenerateCheckSum(msg, len);
}

Points to Note

  • GenerateCheckSum takes the entire FIX message except CheckSum field
  • Delimiter SOH is written as \001 which has ASCII value 1
Community
  • 1
  • 1
kgf3JfUtW
  • 13,702
  • 10
  • 57
  • 80
3
static void Main(string[] args)
    {
        //10=157
        string s = "8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|";
        byte[] bs = GetBytes(s);
        int sum=0;
        foreach (byte b in bs)
            sum = sum + b;
        int checksum = sum % 256;
    }
    //string to byte[]
    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }
anhtv13
  • 1,636
  • 4
  • 30
  • 51
  • 3
    Remark 1: The seperator in FIX messages is the SOH character; not the | symbol (pipe symbol). The byte value of the SOH character is 1. Instead of `"8=FIX.4.2|..."` write `"8=FIX.4.2\u0001..."` – TT. Sep 24 '15 at 09:56
  • 4
    Remark 2: To get a proper byte-array of a string, please refer to the [FieldBase.getTotal method in the QuickFIX/N library](https://github.com/connamara/quickfixn/blob/master/QuickFIXn/Fields/FieldBase.cs). Basically the line `byte[ ] bs = GetBytes(s);` should become `byte[ ] bs = System.Text.Encoding.UTF8.GetBytes( s );` – TT. Sep 24 '15 at 09:58
0

Using BodyLength[9] and CheckSum[10] fields. BodyLength is calculated starting from field starting after BodyLenght and before CheckSum field. CheckSum is calculated from ‘8= upto SOH before the checksum field. Binary value of each character is calculated and compared to the LSB of the calculated value to the checksum value. If the checksum has been calculated to be 274 then the modulo 256 value is 18 (256 + 18 = 274). This value would be transmitted a 10=018 where "10="is the tag for the checksum field.

0

In Java there is a method from QuickFixJ.

String fixStringMessage = "8=FIX.4.29=12535=81=6090706=011=014=017=020=322=837=038=4.39=054=155=ALFAA99=20220829150=0151=06020=06021=06022=F9014=Y";
int checkSum = quickfix.MessageUtils.checksum(fixStringMessage);
System.out.prinln(checkSum);
Output: 127

Hope it can help you.

Gus
  • 1
  • 2