最近在看《编码》这本书,里面谈到了多种编码方式,从摩尔斯电码到盲文,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; }
#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; }