两个校验位计算公式的差异及解释方法咨询
校验位计算公式差异解析
代码示例
#include <stdio.h> int main(void) { int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5, first_sum, second_sum, total; printf("Enter the first single digit : "); scanf("%1d", &d); printf("Enter the first group of five digits : "); scanf("%1d%1d%1d%1d%1d",&i1, &i2,&i3, &i4, &i5 ); printf("Enter the second group of five digits : "); scanf("%1d%1d%1d%1d%1d",&j1, &j2,&j3, &j4, &j5 ); first_sum = d + i2 + i4 + j1 + j3 + j5; second_sum = i1 + i3 + i5 + j2 + j4; total = 3 * first_sum + second_sum; printf("check digit : %d\n", 9 - ((total - 1) % 10)); // 原公式 return 0; }
测试输入
Enter the first single digit : 0 Enter the first group of five digits : 13800 Enter the second group of five digits : 15173
两个公式的差异说明
对比的两个校验位计算公式:
- 原公式:
9 - ((total - 1) % 10) - 修改后公式:
10 - (total % 10)
核心差异:处理total为10的倍数的场景
校验位的核心要求是让total + 校验位成为10的整数倍,也就是求total对10的补数,但两个公式的计算逻辑有本质区别:
场景1:total不是10的倍数(如total=12)
- 原公式计算:
(12-1)%10=11%10=1→9-1=8 - 修改后公式:
12%10=2→10-2=8
结果一致,都能得到合法补数(12+8=20,是10的倍数)。
场景2:total是10的倍数(如total=10)
- 原公式计算:
(10-1)%10=9%10=9→9-9=0 - 修改后公式:
10%10=0→10-0=10
结果出现差异:原公式得到0(10+0=10,符合要求),修改后得到10——而校验位要求是0-9的单个数字,此时修改后的公式会生成无效值。
逻辑本质区别
- 原公式通过
(total-1)%10的处理,把total为10倍数的情况转化为9,再用9减去它得到0,始终输出0-9之间的有效数字。 - 修改后的公式在total是10倍数时,会超出单个校验位的合法范围,不符合校验位的设计要求。
简言之,两个公式仅在total为10的倍数时结果不同,原公式能保证输出合法的单个数字校验位,修改后的公式在该场景下会生成无效值。
内容的提问来源于stack exchange,提问作者jincoder
相关产品推荐
相关产品推荐

