http://www.voidcn.com/article/p-kpbzvkjb-cb.html
第一:计算方法理论、算法是如何理解的,如下:
VIN码各位数字的“对应值”:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
A | B | C | D | E | F | G | H | J | K | L | M | N | P | R | S | T | U | V | W | X | Y | Z |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 1 | 2 | 3 | 4 | 5 | 7 | 9 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
VIN码从第1位到第17位的“加权值”:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
8 | 7 | 6 | 5 | 4 | 3 | 2 | 10 |
| 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
计算方法:
VIN码从从第一位开始,码数字的对应值×该位的加权值,计算全部17位的乘积值相加除以11,所得的余数,即为第九位校验值
例子:
车辆识别码:UU6JA69691D713820第九位为9为校验码,我们可以验证下是否正确。
4×8+4×7+6×6+1×5+1×4+6×3+9×2+6×10+1×9+4×8+7×7+1×6+3×5+8×4+2×3+0×0 = 350
350除以11,得31,余9,该余数9即为校验码,和识别码的校验位相同。如果余数为10,则检验位为字母“X”
另外:VIN中不会包含 I、O、Q 三个英文字母
(因为字母I 与 数字1 太相似字母O 和Q与 数字0太相似 为了防止读错和混淆)
c++代码实现:
#include <iostream> #include <stdint.h> static int weight_coefficient[17] = {8,7,6,5,4,3,2,10,'x',9,8,7,6,5,4,3,2}; int VINCheck(const char *vin) { uint8_t result = 0; int value_temp = 0; int step_temp = 0; for (int i=0; i!=17; ++i) { if (vin[i]>=0x30 && vin[i]<=0x39) { //Arabic numerals value_temp = vin[i] - 0x30; } else if (vin[i]>=0x41 && vin[i]<=0x5A && vin[i]!=0x49 && vin[i]!=0x4F && vin[i]!=0x51) { //upper-roman if (vin[i]>=0x41 && vin[i]<=0x49) value_temp = vin[i] - 0x41 + 1; else if(vin[i]>=0x4A && vin[i]<=0x52) value_temp = vin[i] - 0x4A + 1; else if(vin[i]>=0x53 && vin[i]<=0x5A) value_temp = vin[i] - 0x53 + 2; } else { return false; } if (i != 8) { step_temp += value_temp*weight_coefficient[i]; } } result = (uint8_t)(step_temp%11); if (result == 10) { result = 'X'; } else { result += 0x30; } if (result != vin[8]) { return false; } return true; } int main(int argc, char **argv) { std::cout << argv[1] << std::endl; int ret = VINCheck(argv[1]); std::cout << ret << std::endl; }