C 将 20 位数字字符串转换为数字以进行 IBAN 验证
C converting 20 digit string to number for IBAN validation
我正在用 C 语言进行 IBAN 验证。为此,我有一个类似于“2012129431327715102998”的 char*。
现在我想通过取模 97 的值来检查 IBAN。
所以我想做2012129431327715102998 % 97
。
我已经尝试使用 strtoull 转换 char* ,但这给了我一个超出范围的错误。所以我的问题是:如何将此 char* 转换为可以进行模计算的数字?提前致谢
一种不使用额外库的简单方法是记住数学上:mod(a*b, c) == mod(b * mod(a, c), c)
。所以你可以处理 chunks:
中的数字
// suitable for a 32 bits system, can use 8 for a 64 bits one
#define NB 4
/*********************
* Initial is a string containin only digits representing an arbitrary large number
* div in a number < 10000 (because NB is 4)
* ******************/
int large_mod(char *initial, int div) {
char old[1 + (NB * 2)] = ""; // enough room for a remainder and next chunk
long val;
for (unsigned i=0; i<strlen(initial); i+= NB) {
strncat(old, initial + i, NB); // add the new chunk
val = atol(old) % div; // compute the remainder
sprintf(old, "%ld", val); // keep it for next chunk
// printf("%ld ", val); // uncomment for debugging
}
return (int) val;
}
对于 2012129431327715102998 % 97,它给出了预期的 53。
您可以为此编写自定义函数。在部分和上应用模运算符,可以转换任意长度的数字:
#include <stdio.h>
int mod97(const char *s) {
int res = 0;
while (*s >= '0' && *s <= '9') {
res = (res * 10 + (*s++ - '0')) % 97;
}
return res;
}
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
printf("%s -> %d\n", argv[i], mod97(argv[i]));
}
return 0;
}
输出:
./mod97 2012129431327715102998
2012129431327715102998 -> 53
此方法比 wiki 文章中描述的方法更简单、更通用:计算大数的模 97 可以通过将数字分成 9 位数字块并结合模数来实现这些块。这种拆分特定于 97
,并且因为 1000000000 % 97 == 1
而起作用。上述方法适用于最大 INT_MAX / 10
.
的任何模值
我正在用 C 语言进行 IBAN 验证。为此,我有一个类似于“2012129431327715102998”的 char*。
现在我想通过取模 97 的值来检查 IBAN。
所以我想做2012129431327715102998 % 97
。
我已经尝试使用 strtoull 转换 char* ,但这给了我一个超出范围的错误。所以我的问题是:如何将此 char* 转换为可以进行模计算的数字?提前致谢
一种不使用额外库的简单方法是记住数学上:mod(a*b, c) == mod(b * mod(a, c), c)
。所以你可以处理 chunks:
// suitable for a 32 bits system, can use 8 for a 64 bits one
#define NB 4
/*********************
* Initial is a string containin only digits representing an arbitrary large number
* div in a number < 10000 (because NB is 4)
* ******************/
int large_mod(char *initial, int div) {
char old[1 + (NB * 2)] = ""; // enough room for a remainder and next chunk
long val;
for (unsigned i=0; i<strlen(initial); i+= NB) {
strncat(old, initial + i, NB); // add the new chunk
val = atol(old) % div; // compute the remainder
sprintf(old, "%ld", val); // keep it for next chunk
// printf("%ld ", val); // uncomment for debugging
}
return (int) val;
}
对于 2012129431327715102998 % 97,它给出了预期的 53。
您可以为此编写自定义函数。在部分和上应用模运算符,可以转换任意长度的数字:
#include <stdio.h>
int mod97(const char *s) {
int res = 0;
while (*s >= '0' && *s <= '9') {
res = (res * 10 + (*s++ - '0')) % 97;
}
return res;
}
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
printf("%s -> %d\n", argv[i], mod97(argv[i]));
}
return 0;
}
输出:
./mod97 2012129431327715102998
2012129431327715102998 -> 53
此方法比 wiki 文章中描述的方法更简单、更通用:计算大数的模 97 可以通过将数字分成 9 位数字块并结合模数来实现这些块。这种拆分特定于 97
,并且因为 1000000000 % 97 == 1
而起作用。上述方法适用于最大 INT_MAX / 10
.