最近在看《编码》这本书,里面谈到了多种编码方式,从摩尔斯电码到盲文,ASCII码,以及其设计原理。
尤其提到,在编码中,校验位是保证数据完整性很重要的一个设计,我顺手学习了一下身份证号和图书中ISBN号中的校验位,并写了简单的测试代码。
目前我们使用的18位的身份证号,和13位的ISBN号,他们的最后一个数字都是校验位,身份证的最后一位可能有0~10十一个数,而规定校验位只能有一位,所以用‘X’来代替11,‘X’也即是罗马数字中的10的数符。
身份证验证方法:
#include<stdio.h>
#include<string.h>
const char *id = "34052419800101001X";
int weight[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
char map[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
int main()
{
int i, len;
int sum = 0;
if (strlen(id) != 18) {
printf("wrong length!\n");
return -1;
}
for (i=0; i<17; i++) {
sum += ( id[i] - '0' ) * weight[i];
}
if (id[17] == map[sum % 11]) {
printf("verify pass!\n");
} else {
printf("verify error!\n");
return -1;
}
return 0;
}
ISBN验证方法:
#include<stdio.h>
#include<string.h>
const char *isbn = "9787514605099";
int weight[12] = {1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3};
int main()
{
int i, len;
int sum = 0;
int code;
if (strlen(isbn) != 13) {
printf("wrong length!\n");
return -1;
}
for (i=0; i<12; i++) {
sum += (isbn[i] - '0') * weight[i];
}
code = 10 - sum % 10;
if (code == 10) {
code = 0;
}
if (code == (isbn[12] - '0')) {
printf("verify pass!\n");
} else {
printf("verify error!\n");
return -1;
}
return 0;
}