校验码
计算机系统运行时,为了确保数据在传递过程中正确无误,一是提高硬件电路的可靠性,二是提高代码的校验能力,包括查错与纠错。通常使用校验码的方法来检测传送的数据是否出错。其基本思想是把数据可能出现的编码分为两类:合法编码与错误编码。合法编码用于传送数据,错误编码是不允许在数据中出现的编码。合理的设计错误编码以及编码规则,使得数据在传送中出现错误时会变为错误编码,这样就可以检测出接收的数据是否有错。
术语
码字:是指编码系统中的合法编码称为码字。
码距:是指编码系统中任意两个合法编码之间至少有多少个二进制位不同。如:合法编码为11、00,那么11与00之间至少有两个二进制位不同,所以码距为2。
奇偶校验
奇偶校验是一种简单有效的校验方法。这种方法通过在编码中增加一位校验位来使编码中1的个数为奇数或者偶数,从而使码距变为2。对于奇校验来说,它可以检测奇数位出错的编码,但不能发现偶数位出错的编码。也就是说,奇数为1的合法编码发生了奇数位的错误,会导致1的个数不为奇数,从而检出问题。
奇校验例图:
奇校验的校验位,根据数据位的1的个数是否为奇数,来确定校验位应该是0还是1。如果数据位的1的个数是偶数,则校验位补1,使其整个编码的1的个数变为奇数。
偶校验例图:
偶校验的校验位,根据数据位的1的个数是否为偶数,来确定校验位应该是0还是1。如果数据位的1的个数是奇数,则校验位补1,使其整个编码的1的个数变为偶数,如果数据位的1个数为偶数,则校验位补0,使其依然为偶数。
java代码
public class ParityCheck {
/**
* 偶校验
*
* @param checkBytes 需要检查的字节数组
* @param full checkBytes的所有字节累计进行奇偶校验 。true-所有;false-只要有一个字节不通过奇偶校验就直接返回false。
* @return 是否校验通过
*/
public static boolean evenNumberCheck(byte[] checkBytes, boolean full) {
return parityCheck(checkBytes, false, full);
}
/**
* 奇校验
*
* @param checkBytes 需要检查的字节数组
* @param full checkBytes的所有字节累计进行奇偶校验 。true-所有;false-只要有一个字节不通过奇偶校验就直接返回false。
* @return 是否校验通过
*/
public static boolean oddNumberCheck(byte[] checkBytes, boolean full) {
return parityCheck(checkBytes, true, full);
}
/**
* 奇偶校验
*
* @param checkBytes 需要检查的字节数组
* @param odd 是否奇校验。true-校验,false-偶校验
* @param full checkBytes的所有字节累计进行奇偶校验 。true-所有;false-只要有一个字节不通过奇偶校验就直接返回false。
* @return 是否校验通过
*/
public static boolean parityCheck(byte[] checkBytes, boolean odd, boolean full) {
byte checkMask = 0x1;
int oddSum = 0;
int byteSize = 8;//
for (byte checkByte : checkBytes) {
for (int i = 0; i < byteSize; i++) {
if ((checkByte >> i & checkMask) == 1) {
oddSum++;
}
}
if (!full) {
if (!(odd == isOdd(oddSum))) {
return false;
}
oddSum = 0;
}
}
return !full || odd == isOdd(oddSum);
}
/**
* 判断传入的整数是否为奇数
*
* @param checkInt 校验整数
* @return true-奇数;false-偶数
*/
public static boolean isOdd(long checkInt) {
boolean isOddNumber = false;
byte checkMask = 0x1;
if ((checkInt & checkMask) == 1) {//通过校验最后一位是否为1,来判断是否为奇数。
//为1的bit位数量为奇数
isOddNumber = true;
}
return isOddNumber;
}
public static void main(String[] args) {
String bs1 = "01101011";
byte b1 = (byte) Integer.parseInt(bs1, 2);
byte[] checkBytes = new byte[]{b1};
System.out.println("校验码:" + bs1 + " 奇校验:" + oddNumberCheck(checkBytes, false)); //奇数校验
System.out.println("校验码:" + bs1 + " 偶校验:" + evenNumberCheck(checkBytes, false)); //偶数校验
}
}