第一:计算方法理论、算法是如何理解的,如下:
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太相似 为了防止读错和混淆)
下面来看看JAVA和C++代码如何实现:
/**
* 检验VIN格式
* @param vin
* @return
*/
public boolean checkVIN(String vin) {
Map vinMapWeighting = null;
Map vinMapValue = null;
vinMapWeighting = new HashMap();
vinMapValue = new HashMap();
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#includestatic 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 numeralsvalue_temp = vin[i] - 0x30;} else if (vin[i]>=0x41 && vin[i]<=0x5A && vin[i]!=0x49&& vin[i]!=0x4F && vin[i]!=0x51) { //upper-romanif (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