GO、C#、Java实现CRC16同等算法

GO、C#、Java实现同等CRC16算法校验

很多时候我们在做软件功能的时候不只使用一种程序设计语言,往往都是多种开发语言结合实现特定的需求。我讲述一下我在实现HJ212通信协议算法时用到的CRC16校验算法。

Go语言实现CRC16算法

func Crc16(strData string) (string, error) {
	if strData == "" {
		return "", fmt.Errorf("输入字符串不能为空")
	}

	var crc16Lo, crc16Hi byte
	var saveLo, saveHi byte
	bits := []byte(strData)

	crc16Hi = 0xFF
	crc16Lo = 0x00
	for _, b := range bits {
		crc16Lo = crc16Hi
		crc16Hi = 0
		crc16Lo ^= b

		for g := 0; g < 8; g++ {
			saveHi = crc16Hi
			saveLo = crc16Lo
			crc16Hi >>= 1
			crc16Lo >>= 1
			if saveHi%2 == 1 {
				crc16Lo |= 0x80
			}
			if saveLo%2 == 1 {
				crc16Hi ^= 0xA0
				crc16Lo ^= 0x01
			}
		}
	}
	return fmt.Sprintf("%02X%02X", crc16Hi, crc16Lo), nil
}

C#实现CRC16算法

public static string Crc16(string strData)
{
    byte crc16Lo, crc16Hi;
    byte saveLo, saveHi;
    byte[] bits = Encoding.ASCII.GetBytes(strData);
    crc16Hi = 0xFF;
    crc16Lo = 0x00;
    for (int i = 0; i < bits.Length; i++)
    {
        crc16Lo = crc16Hi;
        crc16Hi = 0;
        crc16Lo ^= bits[i];

        for (int g = 0; g < 8; g++)
        {
            saveHi = crc16Hi;
            saveLo = crc16Lo;
            crc16Hi /= 2;
            crc16Lo /= 2;
            if (saveHi % 2 == 1)
            {
                crc16Lo |= 0x80;
            }
            if (saveLo % 2 == 1)
            {
                crc16Hi ^= 0xA0;
                crc16Lo ^= 0x01;
            }
        }
    }
    return crc16Hi.ToString("X2") + crc16Lo.ToString("X2");
}

Java实现CRC16算法

1、默认字符集

public static String crc16(String strData) {
    byte crc16Lo, crc16Hi;
    byte saveLo, saveHi;
    byte[] bits = strData.getBytes(); // 使用默认字符集

    crc16Hi = (byte) 0xFF;
    crc16Lo = 0x00;
    for (int i = 0; i < bits.length; i++) {
        crc16Lo = crc16Hi;
        crc16Hi = 0;
        crc16Lo ^= bits[i];

        for (int g = 0; g < 8; g++) {
            saveHi = crc16Hi;
            saveLo = crc16Lo;
            crc16Hi /= 2;
            crc16Lo /= 2;
            if ((saveHi & 1) == 1) {
                crc16Lo |= 0x80;
            }
            if ((saveLo & 1) == 1) {
                crc16Hi ^= 0xA0;
                crc16Lo ^= 0x01;
            }
        }
    }
    return String.format("%02X%02X", crc16Hi, crc16Lo);
}

2、UTF-8编码

import java.nio.charset.StandardCharsets;

public static String crc16(String strData) {
    byte crc16Lo, crc16Hi;
    byte saveLo, saveHi;
    byte[] bits = strData.getBytes(StandardCharsets.UTF_8); // 使用UTF-8编码

    crc16Hi = (byte) 0xFF;
    crc16Lo = 0x00;
    for (int i = 0; i < bits.length; i++) {
        crc16Lo = crc16Hi;
        crc16Hi = 0;
        crc16Lo ^= bits[i];

        for (int g = 0; g < 8; g++) {
            saveHi = crc16Hi;
            saveLo = crc16Lo;
            crc16Hi /= 2;
            crc16Lo /= 2;
            if ((saveHi & 1) == 1) {
                crc16Lo |= 0x80;
            }
            if ((saveLo & 1) == 1) {
                crc16Hi ^= 0xA0;
                crc16Lo ^= 0x01;
            }
        }
    }
    return String.format("%02X%02X", crc16Hi, crc16Lo);
}

3、GB2312编码

import java.nio.charset.StandardCharsets;

public static String crc16(String strData) {
    if (strData == null) {
        throw new IllegalArgumentException("输入字符串不能为空");
    }

    byte crc16Lo, crc16Hi;
    byte saveLo, saveHi;
    byte[] bits = strData.getBytes(StandardCharsets.GB2312); // 使用GB2312编码

    crc16Hi = (byte) 0xFF;
    crc16Lo = 0x00;
    for (int i = 0; i < bits.length; i++) {
        crc16Lo = crc16Hi;
        crc16Hi = 0;
        crc16Lo ^= bits[i];

        for (int g = 0; g < 8; g++) {
            saveHi = crc16Hi;
            saveLo = crc16Lo;
            crc16Hi /= 2;
            crc16Lo /= 2;
            if ((saveHi & 1) == 1) {
                crc16Lo |= 0x80;
            }
            if ((saveLo & 1) == 1) {
                crc16Hi ^= 0xA0;
                crc16Lo ^= 0x01;
            }
        }
    }
    return String.format("%02X%02X", crc16Hi, crc16Lo);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值