How to calculate this CRC using Python?











up vote
0
down vote

favorite












I need to calculate this CRC using Python for the communication with Aurora (ABB) solar inverter.



This is the document: http://www.drhack.it/images/PDF/AuroraCommunicationProtocol_4_2.pdf
in the last page there are the instructions to calculate the CRC, i need to do that in python.



The message that i have is



MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000")


The results should be:



CRC_L = FF



CRC_H = 2C



Then i need to send the message complete with the CRC like this:



MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000ff2c")


How can i do that in python? Thanks!



Here is the code that i tried:



message = "023b010000000000"

BccLo= int ("FF",16)
BccHi= int("FF", 16)

New = int(message, 16)

New = New ^ BccLo
Tmp=New << 4
New=Tmp ^ New
Tmp=New >> 5
BccLo=BccHi
BccHi= New ^ Tmp
Tmp=New << 3
BccLo=BccLo ^ Tmp
Tmp=New >> 4
BccLo=BccLo ^ Tmp

CRC_L = ~BccLo
CRC_H = ~BccHi









share|improve this question
























  • What have you tried so far?
    – Klaus D.
    Nov 18 at 7:20










  • I tried using the ^ operator, but it doesen't support bytes, maybe i should try to convert the bytes to a number and then recovert it to bytes, i have the fear to mess up something with theese to many conversion.
    – Simone Luconi
    Nov 18 at 7:40










  • i found this code in c#, still i have the same problem if i try to convert it into python: dreamincode.net/forums/topic/193903-crc-calculation-problem
    – Simone Luconi
    Nov 18 at 8:53










  • i tried it in c#, but it doesn't work, the crc is not correct, even if i try with the example messages written by the user.
    – Simone Luconi
    Nov 18 at 9:03










  • Show us some Python code! Here on SO it is expected that you show us the efforts you made to solve the problem.
    – Klaus D.
    Nov 18 at 9:20















up vote
0
down vote

favorite












I need to calculate this CRC using Python for the communication with Aurora (ABB) solar inverter.



This is the document: http://www.drhack.it/images/PDF/AuroraCommunicationProtocol_4_2.pdf
in the last page there are the instructions to calculate the CRC, i need to do that in python.



The message that i have is



MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000")


The results should be:



CRC_L = FF



CRC_H = 2C



Then i need to send the message complete with the CRC like this:



MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000ff2c")


How can i do that in python? Thanks!



Here is the code that i tried:



message = "023b010000000000"

BccLo= int ("FF",16)
BccHi= int("FF", 16)

New = int(message, 16)

New = New ^ BccLo
Tmp=New << 4
New=Tmp ^ New
Tmp=New >> 5
BccLo=BccHi
BccHi= New ^ Tmp
Tmp=New << 3
BccLo=BccLo ^ Tmp
Tmp=New >> 4
BccLo=BccLo ^ Tmp

CRC_L = ~BccLo
CRC_H = ~BccHi









share|improve this question
























  • What have you tried so far?
    – Klaus D.
    Nov 18 at 7:20










  • I tried using the ^ operator, but it doesen't support bytes, maybe i should try to convert the bytes to a number and then recovert it to bytes, i have the fear to mess up something with theese to many conversion.
    – Simone Luconi
    Nov 18 at 7:40










  • i found this code in c#, still i have the same problem if i try to convert it into python: dreamincode.net/forums/topic/193903-crc-calculation-problem
    – Simone Luconi
    Nov 18 at 8:53










  • i tried it in c#, but it doesn't work, the crc is not correct, even if i try with the example messages written by the user.
    – Simone Luconi
    Nov 18 at 9:03










  • Show us some Python code! Here on SO it is expected that you show us the efforts you made to solve the problem.
    – Klaus D.
    Nov 18 at 9:20













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I need to calculate this CRC using Python for the communication with Aurora (ABB) solar inverter.



This is the document: http://www.drhack.it/images/PDF/AuroraCommunicationProtocol_4_2.pdf
in the last page there are the instructions to calculate the CRC, i need to do that in python.



The message that i have is



MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000")


The results should be:



CRC_L = FF



CRC_H = 2C



Then i need to send the message complete with the CRC like this:



MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000ff2c")


How can i do that in python? Thanks!



Here is the code that i tried:



message = "023b010000000000"

BccLo= int ("FF",16)
BccHi= int("FF", 16)

New = int(message, 16)

New = New ^ BccLo
Tmp=New << 4
New=Tmp ^ New
Tmp=New >> 5
BccLo=BccHi
BccHi= New ^ Tmp
Tmp=New << 3
BccLo=BccLo ^ Tmp
Tmp=New >> 4
BccLo=BccLo ^ Tmp

CRC_L = ~BccLo
CRC_H = ~BccHi









share|improve this question















I need to calculate this CRC using Python for the communication with Aurora (ABB) solar inverter.



This is the document: http://www.drhack.it/images/PDF/AuroraCommunicationProtocol_4_2.pdf
in the last page there are the instructions to calculate the CRC, i need to do that in python.



The message that i have is



MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000")


The results should be:



CRC_L = FF



CRC_H = 2C



Then i need to send the message complete with the CRC like this:



MESSAGE_GRID_VOLTAGE = bytes.fromhex("023b010000000000ff2c")


How can i do that in python? Thanks!



Here is the code that i tried:



message = "023b010000000000"

BccLo= int ("FF",16)
BccHi= int("FF", 16)

New = int(message, 16)

New = New ^ BccLo
Tmp=New << 4
New=Tmp ^ New
Tmp=New >> 5
BccLo=BccHi
BccHi= New ^ Tmp
Tmp=New << 3
BccLo=BccLo ^ Tmp
Tmp=New >> 4
BccLo=BccLo ^ Tmp

CRC_L = ~BccLo
CRC_H = ~BccHi






python crc






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 18 at 11:40









PM 2Ring

42.9k43792




42.9k43792










asked Nov 18 at 7:05









Simone Luconi

297




297












  • What have you tried so far?
    – Klaus D.
    Nov 18 at 7:20










  • I tried using the ^ operator, but it doesen't support bytes, maybe i should try to convert the bytes to a number and then recovert it to bytes, i have the fear to mess up something with theese to many conversion.
    – Simone Luconi
    Nov 18 at 7:40










  • i found this code in c#, still i have the same problem if i try to convert it into python: dreamincode.net/forums/topic/193903-crc-calculation-problem
    – Simone Luconi
    Nov 18 at 8:53










  • i tried it in c#, but it doesn't work, the crc is not correct, even if i try with the example messages written by the user.
    – Simone Luconi
    Nov 18 at 9:03










  • Show us some Python code! Here on SO it is expected that you show us the efforts you made to solve the problem.
    – Klaus D.
    Nov 18 at 9:20


















  • What have you tried so far?
    – Klaus D.
    Nov 18 at 7:20










  • I tried using the ^ operator, but it doesen't support bytes, maybe i should try to convert the bytes to a number and then recovert it to bytes, i have the fear to mess up something with theese to many conversion.
    – Simone Luconi
    Nov 18 at 7:40










  • i found this code in c#, still i have the same problem if i try to convert it into python: dreamincode.net/forums/topic/193903-crc-calculation-problem
    – Simone Luconi
    Nov 18 at 8:53










  • i tried it in c#, but it doesn't work, the crc is not correct, even if i try with the example messages written by the user.
    – Simone Luconi
    Nov 18 at 9:03










  • Show us some Python code! Here on SO it is expected that you show us the efforts you made to solve the problem.
    – Klaus D.
    Nov 18 at 9:20
















What have you tried so far?
– Klaus D.
Nov 18 at 7:20




What have you tried so far?
– Klaus D.
Nov 18 at 7:20












I tried using the ^ operator, but it doesen't support bytes, maybe i should try to convert the bytes to a number and then recovert it to bytes, i have the fear to mess up something with theese to many conversion.
– Simone Luconi
Nov 18 at 7:40




I tried using the ^ operator, but it doesen't support bytes, maybe i should try to convert the bytes to a number and then recovert it to bytes, i have the fear to mess up something with theese to many conversion.
– Simone Luconi
Nov 18 at 7:40












i found this code in c#, still i have the same problem if i try to convert it into python: dreamincode.net/forums/topic/193903-crc-calculation-problem
– Simone Luconi
Nov 18 at 8:53




i found this code in c#, still i have the same problem if i try to convert it into python: dreamincode.net/forums/topic/193903-crc-calculation-problem
– Simone Luconi
Nov 18 at 8:53












i tried it in c#, but it doesn't work, the crc is not correct, even if i try with the example messages written by the user.
– Simone Luconi
Nov 18 at 9:03




i tried it in c#, but it doesn't work, the crc is not correct, even if i try with the example messages written by the user.
– Simone Luconi
Nov 18 at 9:03












Show us some Python code! Here on SO it is expected that you show us the efforts you made to solve the problem.
– Klaus D.
Nov 18 at 9:20




Show us some Python code! Here on SO it is expected that you show us the efforts you made to solve the problem.
– Klaus D.
Nov 18 at 9:20












2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










According to the cited document, the algorithm is actually a standard 16 Bit CCITT CRC. This can be calculated with Python' standard crcmod.



Here you go:



import crcmod

# this is a standard CCITT CRC even if it does not look like
# (crcmod applies xorOut to initCrc, so initCrc is in reality 0xffff, not 0)
_CRC_FUNC = crcmod.mkCrcFun(0x11021, initCrc=0, xorOut=0xffff)

data = bytearray.fromhex("023b010000000000")
crc = _CRC_FUNC(data)
data.append(crc & 0xff)
data.append(((crc >> 8) & 0xff))

print (data.hex())


Output:
023b010000000000ff2c






share|improve this answer





















  • crcmod isn't a standard Python module, but I suppose it's easy enough to install from PyPI.
    – PM 2Ring
    Nov 18 at 13:22










  • You're right, crcmod is not part of the standard distribution. You can install it with pip install crcmod. See also pypi.org/project/crcmod
    – Adrian W
    Nov 18 at 16:40


















up vote
1
down vote













You need to apply that algorithm to each byte of your message. A slight complication is that the algorithm given in the Aurora PDF file assumes the calculation is being performed with 8 bit unsigned arithmetic. To handle that in Python we can use a bitmask of 0xff. Here's a slightly optimized version of that code.



def crc_16(msg):
lo = hi = 0xff
mask = 0xff
for new in msg:
new ^= lo
new ^= (new << 4) & mask
tmp = new >> 5
lo = hi
hi = new ^ tmp
lo ^= (new << 3) & mask
lo ^= new >> 4
lo ^= mask
hi ^= mask
return hi << 8 | lo

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


output



2cff = 2c ff




The above code works, but there are simpler ways to calculate CRCs. And we can use a table to speed up the process, if you need to calculate a lot of CRCs.



As the Wikipedia Cyclic redundancy check article mentions, CRC algorithms are usually specified in terms of a polynomial encoded as a hexadecimal number. Here's a function that does that using the reversed polynomial representation.



def crc_16_CCITT(msg):
poly = 0x8408
crc = 0xffff
for byte in msg:
for _ in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
return crc ^ 0xffff


To speed things up, we can compute a table.



def make_crc_table():
poly = 0x8408
table =
for byte in range(256):
crc = 0
for bit in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
table.append(crc)
return table

table = make_crc_table()

def crc_16_fast(msg):
crc = 0xffff
for byte in msg:
crc = table[(byte ^ crc) & 0xff] ^ (crc >> 8)
return crc ^ 0xffff

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16_fast(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


If you like, you can print the table & paste it into your script, so that you don't have to compute the table every time you run the script.






share|improve this answer























  • Thanks, I appreciate the work that you have done to explain the process, but the answer from the user "Adrian W" its simple to implement
    – Simone Luconi
    Nov 18 at 13:02











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53358646%2fhow-to-calculate-this-crc-using-python%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










According to the cited document, the algorithm is actually a standard 16 Bit CCITT CRC. This can be calculated with Python' standard crcmod.



Here you go:



import crcmod

# this is a standard CCITT CRC even if it does not look like
# (crcmod applies xorOut to initCrc, so initCrc is in reality 0xffff, not 0)
_CRC_FUNC = crcmod.mkCrcFun(0x11021, initCrc=0, xorOut=0xffff)

data = bytearray.fromhex("023b010000000000")
crc = _CRC_FUNC(data)
data.append(crc & 0xff)
data.append(((crc >> 8) & 0xff))

print (data.hex())


Output:
023b010000000000ff2c






share|improve this answer





















  • crcmod isn't a standard Python module, but I suppose it's easy enough to install from PyPI.
    – PM 2Ring
    Nov 18 at 13:22










  • You're right, crcmod is not part of the standard distribution. You can install it with pip install crcmod. See also pypi.org/project/crcmod
    – Adrian W
    Nov 18 at 16:40















up vote
2
down vote



accepted










According to the cited document, the algorithm is actually a standard 16 Bit CCITT CRC. This can be calculated with Python' standard crcmod.



Here you go:



import crcmod

# this is a standard CCITT CRC even if it does not look like
# (crcmod applies xorOut to initCrc, so initCrc is in reality 0xffff, not 0)
_CRC_FUNC = crcmod.mkCrcFun(0x11021, initCrc=0, xorOut=0xffff)

data = bytearray.fromhex("023b010000000000")
crc = _CRC_FUNC(data)
data.append(crc & 0xff)
data.append(((crc >> 8) & 0xff))

print (data.hex())


Output:
023b010000000000ff2c






share|improve this answer





















  • crcmod isn't a standard Python module, but I suppose it's easy enough to install from PyPI.
    – PM 2Ring
    Nov 18 at 13:22










  • You're right, crcmod is not part of the standard distribution. You can install it with pip install crcmod. See also pypi.org/project/crcmod
    – Adrian W
    Nov 18 at 16:40













up vote
2
down vote



accepted







up vote
2
down vote



accepted






According to the cited document, the algorithm is actually a standard 16 Bit CCITT CRC. This can be calculated with Python' standard crcmod.



Here you go:



import crcmod

# this is a standard CCITT CRC even if it does not look like
# (crcmod applies xorOut to initCrc, so initCrc is in reality 0xffff, not 0)
_CRC_FUNC = crcmod.mkCrcFun(0x11021, initCrc=0, xorOut=0xffff)

data = bytearray.fromhex("023b010000000000")
crc = _CRC_FUNC(data)
data.append(crc & 0xff)
data.append(((crc >> 8) & 0xff))

print (data.hex())


Output:
023b010000000000ff2c






share|improve this answer












According to the cited document, the algorithm is actually a standard 16 Bit CCITT CRC. This can be calculated with Python' standard crcmod.



Here you go:



import crcmod

# this is a standard CCITT CRC even if it does not look like
# (crcmod applies xorOut to initCrc, so initCrc is in reality 0xffff, not 0)
_CRC_FUNC = crcmod.mkCrcFun(0x11021, initCrc=0, xorOut=0xffff)

data = bytearray.fromhex("023b010000000000")
crc = _CRC_FUNC(data)
data.append(crc & 0xff)
data.append(((crc >> 8) & 0xff))

print (data.hex())


Output:
023b010000000000ff2c







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 18 at 12:12









Adrian W

1,67131320




1,67131320












  • crcmod isn't a standard Python module, but I suppose it's easy enough to install from PyPI.
    – PM 2Ring
    Nov 18 at 13:22










  • You're right, crcmod is not part of the standard distribution. You can install it with pip install crcmod. See also pypi.org/project/crcmod
    – Adrian W
    Nov 18 at 16:40


















  • crcmod isn't a standard Python module, but I suppose it's easy enough to install from PyPI.
    – PM 2Ring
    Nov 18 at 13:22










  • You're right, crcmod is not part of the standard distribution. You can install it with pip install crcmod. See also pypi.org/project/crcmod
    – Adrian W
    Nov 18 at 16:40
















crcmod isn't a standard Python module, but I suppose it's easy enough to install from PyPI.
– PM 2Ring
Nov 18 at 13:22




crcmod isn't a standard Python module, but I suppose it's easy enough to install from PyPI.
– PM 2Ring
Nov 18 at 13:22












You're right, crcmod is not part of the standard distribution. You can install it with pip install crcmod. See also pypi.org/project/crcmod
– Adrian W
Nov 18 at 16:40




You're right, crcmod is not part of the standard distribution. You can install it with pip install crcmod. See also pypi.org/project/crcmod
– Adrian W
Nov 18 at 16:40












up vote
1
down vote













You need to apply that algorithm to each byte of your message. A slight complication is that the algorithm given in the Aurora PDF file assumes the calculation is being performed with 8 bit unsigned arithmetic. To handle that in Python we can use a bitmask of 0xff. Here's a slightly optimized version of that code.



def crc_16(msg):
lo = hi = 0xff
mask = 0xff
for new in msg:
new ^= lo
new ^= (new << 4) & mask
tmp = new >> 5
lo = hi
hi = new ^ tmp
lo ^= (new << 3) & mask
lo ^= new >> 4
lo ^= mask
hi ^= mask
return hi << 8 | lo

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


output



2cff = 2c ff




The above code works, but there are simpler ways to calculate CRCs. And we can use a table to speed up the process, if you need to calculate a lot of CRCs.



As the Wikipedia Cyclic redundancy check article mentions, CRC algorithms are usually specified in terms of a polynomial encoded as a hexadecimal number. Here's a function that does that using the reversed polynomial representation.



def crc_16_CCITT(msg):
poly = 0x8408
crc = 0xffff
for byte in msg:
for _ in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
return crc ^ 0xffff


To speed things up, we can compute a table.



def make_crc_table():
poly = 0x8408
table =
for byte in range(256):
crc = 0
for bit in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
table.append(crc)
return table

table = make_crc_table()

def crc_16_fast(msg):
crc = 0xffff
for byte in msg:
crc = table[(byte ^ crc) & 0xff] ^ (crc >> 8)
return crc ^ 0xffff

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16_fast(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


If you like, you can print the table & paste it into your script, so that you don't have to compute the table every time you run the script.






share|improve this answer























  • Thanks, I appreciate the work that you have done to explain the process, but the answer from the user "Adrian W" its simple to implement
    – Simone Luconi
    Nov 18 at 13:02















up vote
1
down vote













You need to apply that algorithm to each byte of your message. A slight complication is that the algorithm given in the Aurora PDF file assumes the calculation is being performed with 8 bit unsigned arithmetic. To handle that in Python we can use a bitmask of 0xff. Here's a slightly optimized version of that code.



def crc_16(msg):
lo = hi = 0xff
mask = 0xff
for new in msg:
new ^= lo
new ^= (new << 4) & mask
tmp = new >> 5
lo = hi
hi = new ^ tmp
lo ^= (new << 3) & mask
lo ^= new >> 4
lo ^= mask
hi ^= mask
return hi << 8 | lo

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


output



2cff = 2c ff




The above code works, but there are simpler ways to calculate CRCs. And we can use a table to speed up the process, if you need to calculate a lot of CRCs.



As the Wikipedia Cyclic redundancy check article mentions, CRC algorithms are usually specified in terms of a polynomial encoded as a hexadecimal number. Here's a function that does that using the reversed polynomial representation.



def crc_16_CCITT(msg):
poly = 0x8408
crc = 0xffff
for byte in msg:
for _ in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
return crc ^ 0xffff


To speed things up, we can compute a table.



def make_crc_table():
poly = 0x8408
table =
for byte in range(256):
crc = 0
for bit in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
table.append(crc)
return table

table = make_crc_table()

def crc_16_fast(msg):
crc = 0xffff
for byte in msg:
crc = table[(byte ^ crc) & 0xff] ^ (crc >> 8)
return crc ^ 0xffff

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16_fast(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


If you like, you can print the table & paste it into your script, so that you don't have to compute the table every time you run the script.






share|improve this answer























  • Thanks, I appreciate the work that you have done to explain the process, but the answer from the user "Adrian W" its simple to implement
    – Simone Luconi
    Nov 18 at 13:02













up vote
1
down vote










up vote
1
down vote









You need to apply that algorithm to each byte of your message. A slight complication is that the algorithm given in the Aurora PDF file assumes the calculation is being performed with 8 bit unsigned arithmetic. To handle that in Python we can use a bitmask of 0xff. Here's a slightly optimized version of that code.



def crc_16(msg):
lo = hi = 0xff
mask = 0xff
for new in msg:
new ^= lo
new ^= (new << 4) & mask
tmp = new >> 5
lo = hi
hi = new ^ tmp
lo ^= (new << 3) & mask
lo ^= new >> 4
lo ^= mask
hi ^= mask
return hi << 8 | lo

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


output



2cff = 2c ff




The above code works, but there are simpler ways to calculate CRCs. And we can use a table to speed up the process, if you need to calculate a lot of CRCs.



As the Wikipedia Cyclic redundancy check article mentions, CRC algorithms are usually specified in terms of a polynomial encoded as a hexadecimal number. Here's a function that does that using the reversed polynomial representation.



def crc_16_CCITT(msg):
poly = 0x8408
crc = 0xffff
for byte in msg:
for _ in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
return crc ^ 0xffff


To speed things up, we can compute a table.



def make_crc_table():
poly = 0x8408
table =
for byte in range(256):
crc = 0
for bit in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
table.append(crc)
return table

table = make_crc_table()

def crc_16_fast(msg):
crc = 0xffff
for byte in msg:
crc = table[(byte ^ crc) & 0xff] ^ (crc >> 8)
return crc ^ 0xffff

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16_fast(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


If you like, you can print the table & paste it into your script, so that you don't have to compute the table every time you run the script.






share|improve this answer














You need to apply that algorithm to each byte of your message. A slight complication is that the algorithm given in the Aurora PDF file assumes the calculation is being performed with 8 bit unsigned arithmetic. To handle that in Python we can use a bitmask of 0xff. Here's a slightly optimized version of that code.



def crc_16(msg):
lo = hi = 0xff
mask = 0xff
for new in msg:
new ^= lo
new ^= (new << 4) & mask
tmp = new >> 5
lo = hi
hi = new ^ tmp
lo ^= (new << 3) & mask
lo ^= new >> 4
lo ^= mask
hi ^= mask
return hi << 8 | lo

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


output



2cff = 2c ff




The above code works, but there are simpler ways to calculate CRCs. And we can use a table to speed up the process, if you need to calculate a lot of CRCs.



As the Wikipedia Cyclic redundancy check article mentions, CRC algorithms are usually specified in terms of a polynomial encoded as a hexadecimal number. Here's a function that does that using the reversed polynomial representation.



def crc_16_CCITT(msg):
poly = 0x8408
crc = 0xffff
for byte in msg:
for _ in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
return crc ^ 0xffff


To speed things up, we can compute a table.



def make_crc_table():
poly = 0x8408
table =
for byte in range(256):
crc = 0
for bit in range(8):
if (byte ^ crc) & 1:
crc = (crc >> 1) ^ poly
else:
crc >>= 1
byte >>= 1
table.append(crc)
return table

table = make_crc_table()

def crc_16_fast(msg):
crc = 0xffff
for byte in msg:
crc = table[(byte ^ crc) & 0xff] ^ (crc >> 8)
return crc ^ 0xffff

# Test

msg = bytes.fromhex("023b010000000000")
out = crc_16_fast(msg)
hi, lo = out >> 8, out & 0xff
print('{:04x} = {:02x} {:02x}'.format(out, hi, lo))


If you like, you can print the table & paste it into your script, so that you don't have to compute the table every time you run the script.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 18 at 11:34

























answered Nov 18 at 11:17









PM 2Ring

42.9k43792




42.9k43792












  • Thanks, I appreciate the work that you have done to explain the process, but the answer from the user "Adrian W" its simple to implement
    – Simone Luconi
    Nov 18 at 13:02


















  • Thanks, I appreciate the work that you have done to explain the process, but the answer from the user "Adrian W" its simple to implement
    – Simone Luconi
    Nov 18 at 13:02
















Thanks, I appreciate the work that you have done to explain the process, but the answer from the user "Adrian W" its simple to implement
– Simone Luconi
Nov 18 at 13:02




Thanks, I appreciate the work that you have done to explain the process, but the answer from the user "Adrian W" its simple to implement
– Simone Luconi
Nov 18 at 13:02


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53358646%2fhow-to-calculate-this-crc-using-python%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

If I really need a card on my start hand, how many mulligans make sense? [duplicate]

Alcedinidae

Can an atomic nucleus contain both particles and antiparticles? [duplicate]