1.奇偶校验码
通过在编码中增加一位奇数校验位来使编码中1的个数为奇数(奇校验)或者为偶数(偶校验),从而使码距变为2。
常见的奇偶校验码有三种:水平奇偶校验码、垂直奇偶校验码和水平垂直校验码。
以下是奇偶校验码的示例:
public class ParityCheck {
public static String generateOddParity(String data) {
StringBuilder parity = new StringBuilder();
for (int i = 0; i data.length(); i++) {
int par = 0; // 记录奇数位的个数
for (int j = 0; j 8; j++) {
if (((data.charAt(i) >> j) & 1) == 1) {
par++;
}
}
parity.append((par % 2 == 0) ? '0' : '1'); // 如果奇数位个数为偶数则补1,否则补0
}
return parity.toString();
}
public static String generateEvenParity(String data) {
StringBuilder parity = new StringBuilder();
for (int i = 0; i data.length(); i++) {
int par = 0; // 记录偶数位的个数
for (int j = 0; j 8; j++) {
if (((data.charAt(i) >> j) & 1) == 1) {
par++;
}
}
parity.append((par % 2 == 0) ? '0' : '1'); // 如果偶数位个数为偶数则补1,否则补0
}
return parity.toString();
}
public static void main(String[] args) {
String data = "Hello"; // 示例数据
String oddParity = generateOddParity(data);
String evenParity = generateEvenParity(data);
System.out.println("Odd Parity: " + oddParity);
System.out.println("Even Parity: " + evenParity);
}
}
2.海明码
海明码是由贝尔实验室的Richard Hamming设计的,是一种利用奇偶性来检错和纠错的校验方法。海明码的构成方法是在数据位之间的特定位置上插入K个校验位,通过扩大码距来实现检错和纠错。
设数据位为n位,校验位为k位,则n和k必须满足以下关系:
2
k
−
1
>
=
n
+
k
2^k-1>=n+k
2k−1>=n+k
public class HammingCode {
// 计算海明码的位数
public static int calculateHammingCodeLength(int dataBits, int parityBits) {
return dataBits + parityBits;
}
// 生成海明码
public static int[] generateHammingCode(int[] dataCode, int[] parityCode, int[] hammingCode, int dataBits, int parityBits) {
for (int i = 0; i dataBits; i++) {
hammingCode[i] = dataCode[i];
}
for (int i = 0; i parityBits; i++) {
hammingCode[dataBits + i] = parityCode[i];
}
return hammingCode;
}
// 检查海明码是否有错误
public static boolean checkHammingCode(int[] hammingCode, int dataBits, int parityBits) {
for (int i = 0; i parityBits; i++) {
int mask = 1 (dataBits + i);
int sum = 0;
for (int j = 0; j dataBits; j++) {
if ((hammingCode[j] & mask) != 0) {
sum++;
}
}
if (sum % 2 != hammingCode[dataBits + i]) {
return false;
}
}
return true;
}
// 纠错海明码
public static boolean correctHammingCode(int[] hammingCode, int dataBits, int parityBits) {
for (int i = 0; i parityBits; i++) {
int mask = 1 (dataBits + i);
int sum = 0;
for (int j = 0; j dataBits; j++) {
if ((hammingCode[j] & mask) != 0) {
sum++;
}
}
if (sum % 2 != hammingCode[dataBits + i]) {
hammingCode[dataBits + i] = 1 - hammingCode[dataBits + i]; // 翻转错误位
return true;
}
}
return false;
}
public static void main(String[] args) {
int dataBits = 3; // 数据位数
int parityBits = 2; // 奇偶校验位数
int totalBits = calculateHammingCodeLength(dataBits, parityBits);
int[] dataCode = {0, 0, 1}; // 数据码字
int[] parityCode = new int[parityBits]; // 奇偶校验码字
int[] hammingCode = new int[totalBits]; // 海明码
// 生成海明码
generateHammingCode(dataCode, parityCode, hammingCode, dataBits, parityBits);
// 检查海明码是否有错误
boolean isValid = checkHammingCode(hammingCode, dataBits, parityBits);
System.out.println("Is the Hamming Code valid? " + isValid);
// 模拟一位错误
hammingCode[1] = 1 - hammingCode[1];
// 纠错海明码
boolean isCorrected = correctHammingCode(hammingCode, dataBits, parityBits);
System.out.println("Was the error corrected? " + isCorrected);
// 打印纠正后的海明码
for (int code : hammingCode) {
System.out.print(code);
}
}
}
3.循环冗余校验码
循环冗余校验码(又叫CRC校验码)广泛应用于数据通信领域和磁介质存储系统中。它利用生成多项式为k个数据位产生r个校验码来进行编码。循环冗余校验码由两部分组成,一部分为信息码,另一部分为校验码。如果信息码占
k
k
k位,则校验码就占
n
−
k
n-k
n−k位,其中,n为CRC码的字长,所以又称为
(
n
,
k
)
服务器托管网 (n,k)
(n,k)码。在求CRC编码时,采用的是模2运算,模2加减运算的规则是按位运算,不发生错位和进位。
CRC校验码常用的类别有以下几种:
(1)CRC-8: 生成多项式为
X
8
+
X
2
+
X
+
1
X8+X2+X+1
X8+X2+X+1
(2)CRC-16: 生成多项式为
X
16
+
X
15
+
X
2
+
1
X16+X15+X2+1
X16+X15+X2+1,一般常用于modbus协议
(3)CRC-32:生成多项式为:
X
32
+
X
26
+
X
23
+
X
22
+
X
16
+
X
12
+
X
11
+
X
10
+
X
8
+
X
7
+
X
5
+
X
4
+
X
2
+
X
+
1
X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1
X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1,一般常用于ZIP, RAR, IEEE 802 LAN/FDDI等。
以下是关于CRC-16的应用示例:
import java.nio.charset.StandardCharsets;
public class CRC16 {
public static int crc16Ccitt(byte[] data) {
int crc = 0xFFFF; // 初始值
for (byte b : data) {
for (int i = 0; i 8; i++) {
boolean bit = ((b >> (7 - i) & 1) == 1);
服务器托管网 boolean c15 = ((crc >> 15 & 1) == 1);
crc 1;
if (c15 ^ bit) {
crc ^= 0x1021; // CRC-CCITT多项式
}
}
}
return crc & 0xFFFF; // 确保结果是16位
}
public static void main(String[] args) {
String data = "Hello, CRC!";
int crc = crc16Ccitt(data.getBytes(StandardCharsets.UTF_8));
String hexCrc = Integer.toHexString(crc);
System.out.println("CRC16-CCITT Checksum: " + (hexCrc.length() == 4 ? "0x" + hexCrc : hexCrc));
}
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
SDS与C字符串的区别 二进制安全 C字符串中的字符必须符合某种编码(比如ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串结尾,这些限制使得C字符串只能保存文本数据,而不能保存像图片、音频、视频、压…