How to calculate CheckSum in FIX manually?
Asked Answered
P

5

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?

Polystyrene answered 22/9, 2015 at 3:53 Comment(0)
J
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 );   
}
Jitter answered 22/9, 2015 at 9:22 Comment(6)
"sum every byte in the message". Can you write it in this case?Polystyrene
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?Polystyrene
@ANguyen Quickfix is a library that can produce a FIX message for you. A FIX message is a string consisting of ASCII characters. 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.Jitter
@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.Jitter
When I compile that example C program and use the wiki page test case, it gives me 70, not 65 as wiki saysFile
@File Did you replace the pipe symbols (|) in the example by the SOH character (ASCII code 0x01)?Jitter
Y
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
Yukyukaghir answered 10/11, 2016 at 15:59 Comment(0)
P
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;
    }
Polystyrene answered 24/9, 2015 at 2:46 Comment(2)
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..."Jitter
Remark 2: To get a proper byte-array of a string, please refer to the FieldBase.getTotal method in the QuickFIX/N library. Basically the line byte[ ] bs = GetBytes(s); should become byte[ ] bs = System.Text.Encoding.UTF8.GetBytes( s );Jitter
D
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.

Defense answered 7/3, 2021 at 5:5 Comment(0)
F
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.

Fearless answered 15/12, 2022 at 18:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.