第一:计算方法理论、算法是如何理解的,如下:
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 | 0 | 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太相似 为了防止读错和混淆)
下面来看看JAVA和C++代码如何实现:
/** * 检验VIN格式 * @param vin * @return */ public boolean checkVIN(String vin) { Map<Integer, Integer> vinMapWeighting = null; Map<Character, Integer> vinMapValue = null; vinMapWeighting = new HashMap<Integer, Integer>(); vinMapValue = new HashMap<Character, Integer>(); vinMapWeighting.put(1, 8); vinMapWeighting.put(2, 7); vinMapWeighting.put(3, 6); vinMapWeighting.put(4, 5); vinMapWeighting.put(5, 4); vinMapWeighting.put(6, 3); vinMapWeighting.put(7, 2); vinMapWeighting.put(8, 10); vinMapWeighting.put(9, 0); vinMapWeighting.put(10, 9); vinMapWeighting.put(11, 8); vinMapWeighting.put(12, 7); vinMapWeighting.put(13, 6); vinMapWeighting.put(14, 5); vinMapWeighting.put(15, 4); vinMapWeighting.put(16, 3); vinMapWeighting.put(17, 2); vinMapValue.put('0', 0); vinMapValue.put('1', 1); vinMapValue.put('2', 2); vinMapValue.put('3', 3); vinMapValue.put('4', 4); vinMapValue.put('5', 5); vinMapValue.put('6', 6); vinMapValue.put('7', 7); vinMapValue.put('8', 8); vinMapValue.put('9', 9); vinMapValue.put('A', 1); vinMapValue.put('B', 2); vinMapValue.put('C', 3); vinMapValue.put('D', 4); vinMapValue.put('E', 5); vinMapValue.put('F', 6); vinMapValue.put('G', 7); vinMapValue.put('H', 8); vinMapValue.put('J', 1); vinMapValue.put('K', 2); vinMapValue.put('M', 4); vinMapValue.put('L', 3); vinMapValue.put('N', 5); vinMapValue.put('P', 7); vinMapValue.put('R', 9); vinMapValue.put('S', 2); vinMapValue.put('T', 3); vinMapValue.put('U', 4); vinMapValue.put('V', 5); vinMapValue.put('W', 6); vinMapValue.put('X', 7); vinMapValue.put('Y', 8); vinMapValue.put('Z', 9); boolean reultFlag = false; String uppervin = vin.toUpperCase(); //排除字母O、I if (vin == null || uppervin.indexOf("O") >= 0|| uppervin.indexOf("I") >= 0) { reultFlag = false; } else { //1:长度为17 if (vin.length() == 17) { char[] vinArr = uppervin.toCharArray(); int amount = 0; for (int i = 0; i < vinArr.length; i++) { //VIN码从从第一位开始,码数字的对应值×该位的加权值,计算全部17位的乘积值相加 amount += vinMapValue.get(vinArr[i])*vinMapWeighting.get(i + 1); } //乘积值相加除以11、若余数为10,即为字母X if (amount % 11 == 10) { if (vinArr[8] == 'X') { reultFlag = true; } else { reultFlag = false; } } else { //VIN码从从第一位开始,码数字的对应值×该位的加权值, //计算全部17位的乘积值相加除以11,所得的余数,即为第九位校验值 if (amount % 11 != vinMapValue.get(vinArr[8])) { reultFlag = false; } else { reultFlag = true; } } } //1:长度不为17 if (!vin.equals("") && vin.length() != 17) { reultFlag = false; } } return reultFlag; }下面来看看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; }
文档下载地址
http://download.csdn.net/detail/shenhonglei1234/9677969