/************************************************************************************\
* file name : CRC.groovy *
* description : this is a groovy-script file, used for crc-calculation *
* author : [email protected] *
* CAUTION : the crc-remainder length must be multiple of 4: crc4/8/12/16, etc. *
\************************************************************************************/
class CRC
{
static void main(args)
{
//application example
//1. specify generator polynomial(hex format)
def g_hex = "1021";
//2. specify crc-ini data(hex format)
def c_ini = "0000";
//3. specify source data(hex format)
def d_hex = "110210";
//4. crc-calculate(hex format)
def c_hex = "";
//4-1 normal usage
c_hex = CRC.crcCalc(g_hex, d_hex, c_ini);
println(c_hex);
//4-2 not-operation upon crc-result
c_hex = CRC.hexBitNot(CRC.crcCalc(g_hex, d_hex, c_ini));
println(c_hex);
//4-3 byte-reverse upon source data
c_hex = CRC.crcCalc(g_hex, CRC.hexByteRev(d_hex), c_ini);
println(c_hex);
//4-4 some other usages ...
}
//hex-str to bit-str
def static String hexToBit(hex)
{
def bit = '';
for(c in hex)
bit += String.format('%4s', Integer.toString(Integer.parseInt(c, 16), 2)).replace(' ', '0');
return bit;
}
//bit-str to hex-str
def static String bitToHex(bit)
{
def hex = '';
0.step(bit.length(), 4)
{
idx ->
hex += Integer.toString(Integer.parseInt(bit[idx..idx+3], 2), 16).toUpperCase();
}
return hex;
}
//byte-reverse for hex-str
def static String hexByteRev(hex)
{
assert hex.length()%2 == 0
def hexRev = '';
0.step(hex.length(), 2)
{
idx ->
hexRev += bitToHex(hexToBit(hex[idx..idx+1]).reverse());
}
return hexRev;
}
//not-operation upon hex-str
def static String hexBitNot(hex)
{
def hexNot = '';
for(ch in hex)
hexNot += Integer.toString((~Integer.parseInt(ch, 16)) & 0xF, 16).toUpperCase();
return hexNot;
}
//crc-calculate
def static String crcCalc(g_hex, d_hex, c_ini)
{
assert g_hex.length() == c_ini.length()
def c_bitList = CRC.hexToBit(c_ini).toList();
def g_bitList = CRC.hexToBit(g_hex).toList();
for(ch in d_hex)
{
def d_bitList = CRC.hexToBit(ch).toList();
for(bit in d_bitList)
{
def fed = c_bitList[0] as Integer ^
bit as Integer
for(i in 0..g_bitList.size()-2) c_bitList[i] = c_bitList[i+1] as Integer ^
(g_bitList[i] as Integer & fed)
c_bitList[g_bitList.size()-1] = fed
}
}
def c_hex = CRC.bitToHex(c_bitList.join());
return c_hex
}
}