Please, help me to convert a Python code to C++

May 11, 2018 at 11:55am
Hello Forumers!

I am new to C++, but I have to write a simple program to calculate the CRC16 of a Modbus string.
I have only to write that, I have not to do anything else.

The program writed in Python is the following:

[coode]
def crc16(data, bits=8):
crc = 0xFFFF
for op, code in zip(data[0::2], data[1::2]):
crc = crc ^ int(op+code, 16)
for bit in range(0, bits):
if (crc&0x0001) == 0x0001:
crc = ((crc >> 1) ^ 0xA001)
else:
crc = crc >> 1
msb = crc >> 8
lsb = crc & 0x00FF
return '{:X}{:X}'.format(lsb, msb)
[/code]


For example, with the string "11010003000C" the output of the conversion must be "CE9F".
I need only that function for my first and I think only program in C++.

Someone could help me please?

Thanks a lot in advance!
Last edited on May 11, 2018 at 11:56am
May 11, 2018 at 1:34pm
If you already have functional code, then why should you rewrite it in another language, like C++?

Are you fluent in Python, i.e. know the existing algorithm's logic intimately?

Have you done a websearch with "CRC16 of a Modbus string"?
May 11, 2018 at 1:40pm
Thanks for the reply! But I need the code in C++ because I have to insert it in a QT project, and I can't use Python.

I'm not fluent in python, but I'm studying it, but for now I need only that function in C++ for a small project, then I will use only Python probabily
May 11, 2018 at 2:56pm
Let's try a different approach. This python function looks a little sparse for something like redundancy checking so we're going to drop it on the floor and look at a C\C++ solution instead. Check here: https://github.com/d-bahr/CRCpp .Why is it only 16-bit? Is that a requirement?
May 11, 2018 at 3:24pm
Bokka, i call BS, that's not Python. Python is all about indentation, and your post is completely left-aligned. Can't even tell when the nested(?) for loops end.

The zip() with extended slices of 2 just assigns "op" to every even index element of data, and "code" to every odd index of data. The zip seems unnecessary to me since it's zipping from the same array. Then again, I come from Ruby background, not python.

The range() is just up to but not including bits. So a normal indexed loop.

Rest is math and a formatted string at the end.
May 11, 2018 at 3:30pm
Well, just guess+check I found out the indentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def crc16(data, bits=8):
    crc = 0xFFFF
    for op, code in zip(data[0::2], data[1::2]):
        crc = crc ^ int(op+code, 16)
        for bit in range(0, bits):
            if (crc&0x0001) == 0x0001:
                crc = ((crc >> 1) ^ 0xA001)
            else:
                crc = crc >> 1
    msb = crc >> 8
    lsb = crc & 0x00FF
    return '{:X}{:X}'.format(lsb, msb)

print(crc16("11010003000C"))


Running at https://repl.it/repls/ComposedSevereApache
CE9F
May 11, 2018 at 3:30pm
The python code is not indented because the forum won't allow me to do it.

Btw I repeat it, I need only that part of code for my first and probabily last C++ project.

For computerGeek01: yes, I need only a 16 bit check, I don't need another things
May 11, 2018 at 3:49pm
Google offers for me now: https://stackoverflow.com/questions/19347685/calculating-modbus-rtu-crc-16

Is that the same algorithm?
May 11, 2018 at 4:07pm
Upon closer inspection, "op" and "code" are basically unused. They just wanted the substring of every two characters. std::hex returns lowercase hex by default, so that's why std::uppercase is employed here as well.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

string Crc16(const string& data, unsigned short bits=8)
{
    unsigned short crc = 0xFFFF;
    for (int i=0; i<data.size(); i+=2)
    {
        crc = crc ^ stoi(data.substr(i,2), nullptr, 16);
        for (int x=0; x<bits; ++x)
        {
            if (crc&0x0001 == 0x0001)
                crc =  (crc>>1) ^ 0xA001;
            else
                crc = crc >> 1;
        }
    }
    ostringstream oss;
    oss << uppercase << hex << (crc&0x00FF) << (crc>>8);
    return oss.str();
}

int main()
{
    cout << Crc16("11010003000C") << endl;
    return 0;
}


Running at https://repl.it/repls/AltruisticEthicalZettabyte
CE9F

May 11, 2018 at 8:22pm
EXACTLY what I want! YOU are my HERO! Thanks a lot to everybody!!!
Topic archived. No new replies allowed.