Java中字符串转十六进制及CRC16加密实现困惑求解
解决CRC16计算及字符串转十六进制的问题
首先得澄清下:CRC16其实是一种循环冗余校验算法,并不是加密算法,但我明白你是想基于字符串计算它的CRC16校验值,而且需要先把字符串转成十六进制格式对吧?下面我一步步帮你实现:
第一步:字符串转十六进制格式
你当前的代码已经把字符串转成了字节数组,接下来可以把这个字节数组转换成十六进制字符串。这里给你一个实用的工具方法:
public static String bytesToHex(byte[] bytes) { StringBuilder hexString = new StringBuilder(); for (byte b : bytes) { String hex = Integer.toHexString(0xff & b); // 补0保证单字节的十六进制是两位 if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); }
把这个方法加到你的代码里,调用后就能得到字符串的十六进制格式:
String hexStr = bytesToHex(valuesDefault); System.out.println("十六进制格式:" + hexStr); // 对于输入"skn",输出会是736b6e
第二步:计算CRC16校验值
Java本身没有内置的CRC16实现,我们可以自己实现一个通用的CRC-16-CCITT标准算法(这是最常用的CRC16规格之一):
public static int calculateCRC16(byte[] bytes) { int crc = 0xFFFF; // CRC16的初始值 int polynomial = 0x1021; // CRC-16-CCITT的多项式 for (byte b : bytes) { crc ^= (b << 8); for (int i = 0; i < 8; i++) { if ((crc & 0x8000) != 0) { crc = (crc << 1) ^ polynomial; } else { crc <<= 1; } } } return crc & 0xFFFF; // 确保结果是16位整数 }
你可以直接用原字符串的字节数组计算CRC16,也可以把十六进制字符串转回字节数组后计算(如果业务要求的话):
// 直接用原字节数组计算CRC16 int crcValue = calculateCRC16(valuesDefault); System.out.println("CRC16十进制值:" + crcValue); // 转成十六进制格式的CRC16结果 System.out.println("CRC16十六进制值:" + Integer.toHexString(crcValue).toUpperCase());
整合后的完整代码
把这些方法整合到你的main方法里,完整代码如下:
import java.util.Arrays; public class CRC16Example { public static void main(String[] args) { String input = "skn"; byte[] valuesDefault = input.getBytes(); System.out.println("input:" + input); System.out.println("字节数组:" + Arrays.toString(valuesDefault)); // 字符串转十六进制 String hexStr = bytesToHex(valuesDefault); System.out.println("十六进制格式:" + hexStr); // 计算CRC16校验值 int crcValue = calculateCRC16(valuesDefault); System.out.println("CRC16十进制值:" + crcValue); System.out.println("CRC16十六进制值:" + Integer.toHexString(crcValue).toUpperCase()); } // 字节数组转十六进制字符串 public static String bytesToHex(byte[] bytes) { StringBuilder hexString = new StringBuilder(); for (byte b : bytes) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } // CRC16-CCITT算法实现 public static int calculateCRC16(byte[] bytes) { int crc = 0xFFFF; int polynomial = 0x1021; for (byte b : bytes) { crc ^= (b << 8); for (int i = 0; i < 8; i++) { if ((crc & 0x8000) != 0) { crc = (crc << 1) ^ polynomial; } else { crc <<= 1; } } } return crc & 0xFFFF; } }
运行这段代码会得到如下输出:
input:skn
字节数组:[115, 107, 110]
十六进制格式:736b6e
CRC16十进制值:40338
CRC16十六进制值:9D92
另外补充:你提到“要求整数为16字节”,这里可能是指需要把16位的CRC16结果扩展成16字节的数组?如果是这样,可以用ByteBuffer来实现:
import java.nio.ByteBuffer; // 在main方法中添加这段代码 byte[] crc16Bytes = ByteBuffer.allocate(16).putShort((short) crcValue).array(); System.out.println("16字节的CRC16数组:" + Arrays.toString(crc16Bytes));
这样得到的数组前14个字节是0,最后2个字节是CRC16的实际值,满足16字节的要求。
内容的提问来源于stack exchange,提问作者Nurhudayati Mardiah
相关产品推荐
相关产品推荐

