Skip to content

Instantly share code, notes, and snippets.

@meltingrabbit
Last active January 31, 2022 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meltingrabbit/b7279d75cd259d3fe97dc8f63583e391 to your computer and use it in GitHub Desktop.
Save meltingrabbit/b7279d75cd259d3fe97dc8f63583e391 to your computer and use it in GitHub Desktop.
# coding: UTF-8
'''
# 実行結果
IBM: 962b [poly: 8005, init: 0000, refin: 0, refout: 0, xorout: 0000, is_reft: 1]
IBM: d469 [poly: 8005, init: 0000, refin: 0, refout: 1, xorout: 0000, is_reft: 1]
IBM: d9a7 [poly: 8005, init: 0000, refin: 1, refout: 0, xorout: 0000, is_reft: 1]
IBM: e59b [poly: 8005, init: 0000, refin: 1, refout: 1, xorout: 0000, is_reft: 1]
IBM: dd22 [poly: 8005, init: 0000, refin: 0, refout: 0, xorout: 0000, is_reft: 0]
IBM: 44bb [poly: 8005, init: 0000, refin: 0, refout: 1, xorout: 0000, is_reft: 0]
IBM: 9773 [poly: 8005, init: 0000, refin: 1, refout: 0, xorout: 0000, is_reft: 0]
IBM: cee9 [poly: 8005, init: 0000, refin: 1, refout: 1, xorout: 0000, is_reft: 0]
IBM: cee9 [poly: a001, init: 0000, refin: 0, refout: 0, xorout: 0000, is_reft: 1]
IBM: 9773 [poly: a001, init: 0000, refin: 0, refout: 1, xorout: 0000, is_reft: 1]
IBM: 44bb [poly: a001, init: 0000, refin: 1, refout: 0, xorout: 0000, is_reft: 1]
IBM: dd22 [poly: a001, init: 0000, refin: 1, refout: 1, xorout: 0000, is_reft: 1]
IBM: e59b [poly: a001, init: 0000, refin: 0, refout: 0, xorout: 0000, is_reft: 0]
IBM: d9a7 [poly: a001, init: 0000, refin: 0, refout: 1, xorout: 0000, is_reft: 0]
IBM: d469 [poly: a001, init: 0000, refin: 1, refout: 0, xorout: 0000, is_reft: 0]
IBM: 962b [poly: a001, init: 0000, refin: 1, refout: 1, xorout: 0000, is_reft: 0]
CCITT: 4097 [poly: 1021, init: ffff, refin: 0, refout: 0, xorout: 0000, is_reft: 1]
CCITT: e902 [poly: 1021, init: ffff, refin: 0, refout: 1, xorout: 0000, is_reft: 1]
CCITT: 2c58 [poly: 1021, init: ffff, refin: 1, refout: 0, xorout: 0000, is_reft: 1]
CCITT: 1a34 [poly: 1021, init: ffff, refin: 1, refout: 1, xorout: 0000, is_reft: 1]
CCITT: 18d1 [poly: 1021, init: ffff, refin: 0, refout: 0, xorout: 0000, is_reft: 0]
CCITT: 8b18 [poly: 1021, init: ffff, refin: 0, refout: 1, xorout: 0000, is_reft: 0]
CCITT: 1835 [poly: 1021, init: ffff, refin: 1, refout: 0, xorout: 0000, is_reft: 0]
CCITT: ac18 [poly: 1021, init: ffff, refin: 1, refout: 1, xorout: 0000, is_reft: 0]
CCITT: ac18 [poly: 8408, init: ffff, refin: 0, refout: 0, xorout: 0000, is_reft: 1]
CCITT: 1835 [poly: 8408, init: ffff, refin: 0, refout: 1, xorout: 0000, is_reft: 1]
CCITT: 8b18 [poly: 8408, init: ffff, refin: 1, refout: 0, xorout: 0000, is_reft: 1]
CCITT: 18d1 [poly: 8408, init: ffff, refin: 1, refout: 1, xorout: 0000, is_reft: 1]
CCITT: 1a34 [poly: 8408, init: ffff, refin: 0, refout: 0, xorout: 0000, is_reft: 0]
CCITT: 2c58 [poly: 8408, init: ffff, refin: 0, refout: 1, xorout: 0000, is_reft: 0]
CCITT: e902 [poly: 8408, init: ffff, refin: 1, refout: 0, xorout: 0000, is_reft: 0]
CCITT: 4097 [poly: 8408, init: ffff, refin: 1, refout: 1, xorout: 0000, is_reft: 0]
# 結論
右送り,左送りを逆にするというのは,計算ビット順を逆順にすることに等しい.
つまり,生成多項式を反転した上で, refin, xorout をともに反転させることに等しい.
備考
0x8005 のビット列を反転させると 0xa001 になる.
0x8005: 0b1000000000000101
0xa001: 0b1010000000000001
また,ここで言う反転,とは,ビット順の反転であり, 0, 1 の反転ではない.
出力の 0, 1 を反転する時は, xorout = 0xFFFF とすればいい.
'''
def main():
data = [0xDE, 0xAD, 0xBE, 0xEF]
calc_crc16("IBM", data, 0x8005, 0x0000, 0, 0, 0x0000, 1)
calc_crc16("IBM", data, 0x8005, 0x0000, 0, 1, 0x0000, 1)
calc_crc16("IBM", data, 0x8005, 0x0000, 1, 0, 0x0000, 1)
calc_crc16("IBM", data, 0x8005, 0x0000, 1, 1, 0x0000, 1) # 標準
calc_crc16("IBM", data, 0x8005, 0x0000, 0, 0, 0x0000, 0)
calc_crc16("IBM", data, 0x8005, 0x0000, 0, 1, 0x0000, 0)
calc_crc16("IBM", data, 0x8005, 0x0000, 1, 0, 0x0000, 0)
calc_crc16("IBM", data, 0x8005, 0x0000, 1, 1, 0x0000, 0)
calc_crc16("IBM", data, 0xA001, 0x0000, 0, 0, 0x0000, 1)
calc_crc16("IBM", data, 0xA001, 0x0000, 0, 1, 0x0000, 1)
calc_crc16("IBM", data, 0xA001, 0x0000, 1, 0, 0x0000, 1)
calc_crc16("IBM", data, 0xA001, 0x0000, 1, 1, 0x0000, 1)
calc_crc16("IBM", data, 0xA001, 0x0000, 0, 0, 0x0000, 0)
calc_crc16("IBM", data, 0xA001, 0x0000, 0, 1, 0x0000, 0)
calc_crc16("IBM", data, 0xA001, 0x0000, 1, 0, 0x0000, 0)
calc_crc16("IBM", data, 0xA001, 0x0000, 1, 1, 0x0000, 0)
calc_crc16("CCITT", data, 0x1021, 0xFFFF, 0, 0, 0x0000, 1) # 標準
calc_crc16("CCITT", data, 0x1021, 0xFFFF, 0, 1, 0x0000, 1)
calc_crc16("CCITT", data, 0x1021, 0xFFFF, 1, 0, 0x0000, 1)
calc_crc16("CCITT", data, 0x1021, 0xFFFF, 1, 1, 0x0000, 1)
calc_crc16("CCITT", data, 0x1021, 0xFFFF, 0, 0, 0x0000, 0)
calc_crc16("CCITT", data, 0x1021, 0xFFFF, 0, 1, 0x0000, 0)
calc_crc16("CCITT", data, 0x1021, 0xFFFF, 1, 0, 0x0000, 0)
calc_crc16("CCITT", data, 0x1021, 0xFFFF, 1, 1, 0x0000, 0)
calc_crc16("CCITT", data, 0x8408, 0xFFFF, 0, 0, 0x0000, 1)
calc_crc16("CCITT", data, 0x8408, 0xFFFF, 0, 1, 0x0000, 1)
calc_crc16("CCITT", data, 0x8408, 0xFFFF, 1, 0, 0x0000, 1)
calc_crc16("CCITT", data, 0x8408, 0xFFFF, 1, 1, 0x0000, 1)
calc_crc16("CCITT", data, 0x8408, 0xFFFF, 0, 0, 0x0000, 0)
calc_crc16("CCITT", data, 0x8408, 0xFFFF, 0, 1, 0x0000, 0)
calc_crc16("CCITT", data, 0x8408, 0xFFFF, 1, 0, 0x0000, 0)
calc_crc16("CCITT", data, 0x8408, 0xFFFF, 1, 1, 0x0000, 0)
def calc_crc16(msg, data, poly, init, refin, refout, xorout, is_reft):
if is_reft:
crc = _calc_crc16_left(data, poly, init, refin, refout, xorout)
else:
crc = _calc_crc16_right(data, poly, init, refin, refout, xorout)
print(
msg
+ ": "
+ "{:04x}".format(crc)
+ " [poly: "
+ "{:04x}".format(poly)
+ ", init: "
+ "{:04x}".format(init)
+ ", refin: "
+ str(refin)
+ ", refout: "
+ str(refout)
+ ", xorout: "
+ "{:04x}".format(xorout)
+ ", is_reft: "
+ str(is_reft)
+ "]"
)
# ビット列の反転
def _reflect(input, bit_len):
output = 0
for i in range(bit_len):
output = (output << 1) | ((input >> i) & 1)
return output
# 左送り CRC
def _calc_crc16_left(data, poly, init, refin, refout, xorout):
if refin:
init = _reflect(init, 16)
crc = init
for x in data:
if refin:
x = _reflect(x, 8)
crc = crc ^ (x << 8)
for j in range(0, 8):
if crc & 0x8000:
crc = poly ^ (crc << 1)
else:
crc = crc << 1
crc = crc & 0xFFFF
if refout:
crc = _reflect(crc, 16)
return crc ^ xorout
# 右送り CRC
def _calc_crc16_right(data, poly, init, refin, refout, xorout):
if refin:
init = _reflect(init, 16)
crc = init
for x in data:
if refin:
x = _reflect(x, 8)
crc = crc ^ x
for j in range(0, 8):
if crc & 0x0001:
crc = poly ^ (crc >> 1)
else:
crc = crc >> 1
crc = crc & 0xFFFF
if refout:
crc = _reflect(crc, 16)
return crc ^ xorout
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment