1
0
mirror of https://git.code.sf.net/p/zint/code synced 2025-12-20 11:27:09 +00:00

Add verification for North America VIN (Vehicle Identification Number)

This commit is contained in:
Robin Stuart
2018-02-03 18:44:01 +00:00
parent 38150ce931
commit e737f992b5
5 changed files with 146 additions and 38 deletions

View File

@@ -39,6 +39,7 @@
#define SODIUM "0123456789-"
#define SILVER "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd"
#define ARSENIC "0123456789ABCDEFGHJKLMNPRSTUVWXYZ"
static const char *C11Table[11] = {
"111121", "211121", "121121", "221111", "112121", "212111", "122111",
@@ -461,7 +462,7 @@ int c93(struct zint_symbol *symbol, unsigned char source[], int length) {
"It is the intent and understanding of AIM [t]hat the symbology presented in this
specification is entirely in the public domain and free of all use restrictions,
licenses and fees. AIM USA, its memer companies, or individual officers
licenses and fees. AIM USA, its member companies, or individual officers
assume no liability for the use of this document." */
void CheckCharacter() {
@@ -591,3 +592,98 @@ int channel_code(struct zint_symbol *symbol, unsigned char source[], int length)
}
/* Vehicle Identification Number (VIN) */
int vin(struct zint_symbol *symbol, unsigned char source[], int length) {
/* This code verifies the check digit present in North American VIN codes */
int zeros;
char local_source[18];
char dest[200];
char input_check;
char output_check;
int value[17];
int weight[17] = {8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2};
int sum;
int i;
// Check length
if (length > 17) {
strcpy(symbol->errtxt, "336: Input too long");
return ZINT_ERROR_TOO_LONG;
}
// Check input characters, I, O and Q are not allowed
if (is_sane(ARSENIC, source, length) == ZINT_ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "337: Invalid characters in input data");
return ZINT_ERROR_INVALID_DATA;
}
// Pad with zeros
zeros = 17 - length;
for (i = 0; i < 17; i++) {
local_source[i] = '0';
}
local_source[17] = '\0';
for (i = 0; i < length; i++) {
local_source[zeros + i] = source[i];
}
input_check = local_source[8];
for (i = 0; i < 17; i++) {
if ((local_source[i] >= '0') && (local_source[i] <= '9')) {
value[i] = local_source[i] - '0';
}
if ((local_source[i] >= 'A') && (local_source[i] <= 'I')) {
value[i] = (local_source[i] - 'A') + 1;
}
if ((local_source[i] >= 'J') && (local_source[i] <= 'R')) {
value[i] = (local_source[i] - 'J') + 1;
}
if ((local_source[i] >= 'S') && (local_source[i] <= 'Z')) {
value[i] = (local_source[i] - 'S') + 2;
}
}
sum = 0;
for (i = 0; i < 17; i++) {
sum += value[i] * weight[i];
}
output_check = '0' + (sum % 11);
if (output_check == ':') {
// Check digit was 10
output_check = 'X';
}
if (symbol->debug) {
printf("Producing VIN code: %s\n", local_source);
printf("Input check was %c, calculated check is %c\n", input_check, output_check);
}
if (input_check != output_check) {
strcpy(symbol->errtxt, "338: Invalid check digit in input data");
return ZINT_ERROR_INVALID_DATA;
}
/* Start character */
strcpy(dest, "1211212111");
// Copy glyphs to symbol
for (i = 0; i < 17; i++) {
lookup(SILVER, C39Table, local_source[i], dest);
}
/* Stop character */
strcat(dest, "121121211");
ustrcpy(symbol->text, (unsigned char *) local_source);
expand(symbol, dest);
return 0;
}

View File

@@ -171,8 +171,9 @@ extern int han_xin(struct zint_symbol * symbol, const unsigned char source[], si
extern int dotcode(struct zint_symbol * symbol, const unsigned char source[], int length); /* DotCode */
extern int codablock(struct zint_symbol * symbol, const unsigned char source[], const size_t length); /* Codablock */
extern int upnqr(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* UPNQR */
extern int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* Data Matrix (IEC16022) */
extern int dmatrix(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* QR Code */
extern int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* QR Code */
extern int dmatrix(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* Data Matrix (IEC16022) */
extern int vin(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* VIN Code (Vehicle Identification Number) */
extern int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to PNG/BMP/PCX */
extern int render_plot(struct zint_symbol *symbol, float width, float height); /* Plot to gLabels */
@@ -554,6 +555,7 @@ int ZBarcode_ValidID(int symbol_id) {
case BARCODE_DOTCODE:
case BARCODE_CODABLOCKF:
case BARCODE_UPNQR:
case BARCODE_VIN:
result = 1;
break;
}
@@ -773,6 +775,8 @@ static int reduced_charset(struct zint_symbol *symbol, const unsigned char *sour
break;
case BARCODE_CODABLOCKF: error_number = codablock(symbol, preprocessed, in_length);
break;
case BARCODE_VIN: error_number = vin(symbol, preprocessed, in_length);
break;
}
return error_number;
@@ -975,11 +979,6 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
if ((symbol->symbology == 64) || (symbol->symbology == 65)) {
symbol->symbology = BARCODE_AUSPOST;
}
if (symbol->symbology == 73) {
strcpy(symbol->errtxt, "211: Symbology out of range, using Code 128");
symbol->symbology = BARCODE_CODE128;
error_number = ZINT_WARN_INVALID_OPTION;
}
if (symbol->symbology == 78) {
symbol->symbology = BARCODE_RSS14;
}

View File

@@ -151,6 +151,7 @@ extern "C" {
#define BARCODE_RM4SCC 70
#define BARCODE_DATAMATRIX 71
#define BARCODE_EAN14 72
#define BARCODE_VIN 73
#define BARCODE_CODABLOCKF 74
#define BARCODE_NVE18 75
#define BARCODE_JAPANPOST 76