mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Add verification for North America VIN (Vehicle Identification Number)
This commit is contained in:
parent
38150ce931
commit
e737f992b5
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#define SODIUM "0123456789-"
|
#define SODIUM "0123456789-"
|
||||||
#define SILVER "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd"
|
#define SILVER "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd"
|
||||||
|
#define ARSENIC "0123456789ABCDEFGHJKLMNPRSTUVWXYZ"
|
||||||
|
|
||||||
static const char *C11Table[11] = {
|
static const char *C11Table[11] = {
|
||||||
"111121", "211121", "121121", "221111", "112121", "212111", "122111",
|
"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
|
"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,
|
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." */
|
assume no liability for the use of this document." */
|
||||||
|
|
||||||
void CheckCharacter() {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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 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 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 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 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); /* 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 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 */
|
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_DOTCODE:
|
||||||
case BARCODE_CODABLOCKF:
|
case BARCODE_CODABLOCKF:
|
||||||
case BARCODE_UPNQR:
|
case BARCODE_UPNQR:
|
||||||
|
case BARCODE_VIN:
|
||||||
result = 1;
|
result = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -773,6 +775,8 @@ static int reduced_charset(struct zint_symbol *symbol, const unsigned char *sour
|
|||||||
break;
|
break;
|
||||||
case BARCODE_CODABLOCKF: error_number = codablock(symbol, preprocessed, in_length);
|
case BARCODE_CODABLOCKF: error_number = codablock(symbol, preprocessed, in_length);
|
||||||
break;
|
break;
|
||||||
|
case BARCODE_VIN: error_number = vin(symbol, preprocessed, in_length);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return error_number;
|
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)) {
|
if ((symbol->symbology == 64) || (symbol->symbology == 65)) {
|
||||||
symbol->symbology = BARCODE_AUSPOST;
|
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) {
|
if (symbol->symbology == 78) {
|
||||||
symbol->symbology = BARCODE_RSS14;
|
symbol->symbology = BARCODE_RSS14;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,7 @@ extern "C" {
|
|||||||
#define BARCODE_RM4SCC 70
|
#define BARCODE_RM4SCC 70
|
||||||
#define BARCODE_DATAMATRIX 71
|
#define BARCODE_DATAMATRIX 71
|
||||||
#define BARCODE_EAN14 72
|
#define BARCODE_EAN14 72
|
||||||
|
#define BARCODE_VIN 73
|
||||||
#define BARCODE_CODABLOCKF 74
|
#define BARCODE_CODABLOCKF 74
|
||||||
#define BARCODE_NVE18 75
|
#define BARCODE_NVE18 75
|
||||||
#define BARCODE_JAPANPOST 76
|
#define BARCODE_JAPANPOST 76
|
||||||
|
@ -280,6 +280,7 @@ Numeric Value | Barcode Name
|
|||||||
70 | Royal Mail 4 State (RM4SCC)
|
70 | Royal Mail 4 State (RM4SCC)
|
||||||
71 | Data Matrix (ECC200)
|
71 | Data Matrix (ECC200)
|
||||||
72 | EAN-14
|
72 | EAN-14
|
||||||
|
73 | Vehicle Identification Number (America)
|
||||||
74 | Codablock-F
|
74 | Codablock-F
|
||||||
75 | NVE-18
|
75 | NVE-18
|
||||||
76 | Japanese Postal Code
|
76 | Japanese Postal Code
|
||||||
@ -526,6 +527,7 @@ GIF | Graphics Interchange Format
|
|||||||
PCX | ZSoft Paintbrush image
|
PCX | ZSoft Paintbrush image
|
||||||
PNG | Portable Network Graphic
|
PNG | Portable Network Graphic
|
||||||
SVG | Scalable Vector Graphic
|
SVG | Scalable Vector Graphic
|
||||||
|
TIF | Tagged Image File Format
|
||||||
TXT | Text file (see 4.16)
|
TXT | Text file (see 4.16)
|
||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
|
|
||||||
@ -952,6 +954,7 @@ Value |
|
|||||||
70 | BARCODE_RM4SCC | Royal Mail 4 State (RM4SCC)
|
70 | BARCODE_RM4SCC | Royal Mail 4 State (RM4SCC)
|
||||||
71 | BARCODE_DATAMATRIX | Data Matrix ECC200
|
71 | BARCODE_DATAMATRIX | Data Matrix ECC200
|
||||||
72 | BARCODE_EAN14 | EAN-14
|
72 | BARCODE_EAN14 | EAN-14
|
||||||
|
73 | BARCODE_VIN | Vehicle Identification Number (America)
|
||||||
74 | BARCODE_CODABLOCKF | Codablock-F
|
74 | BARCODE_CODABLOCKF | Codablock-F
|
||||||
75 | BARCODE_NVE18 | NVE-18
|
75 | BARCODE_NVE18 | NVE-18
|
||||||
76 | BARCODE_JAPANPOST | Japanese Postal Code
|
76 | BARCODE_JAPANPOST | Japanese Postal Code
|
||||||
@ -1309,6 +1312,12 @@ This option adds a leading '+' character and a trailing modulo-49 check digit
|
|||||||
to a standard Code 39 symbol as required by the Health Industry Barcode
|
to a standard Code 39 symbol as required by the Health Industry Barcode
|
||||||
standards.
|
standards.
|
||||||
|
|
||||||
|
6.1.8.8 Vehicle Identification Number
|
||||||
|
-------------------------------------
|
||||||
|
This option includes a verification stage for vehicle identification numbers
|
||||||
|
used in North America which include a check digit. For European vehicle
|
||||||
|
identification numbers use Standard Code 39.
|
||||||
|
|
||||||
6.1.9 Codabar (EN 798)
|
6.1.9 Codabar (EN 798)
|
||||||
----------------------
|
----------------------
|
||||||
Also known as NW-7, Monarch, ABC Codabar, USD-4, Ames Code and Code 27, this
|
Also known as NW-7, Monarch, ABC Codabar, USD-4, Ames Code and Code 27, this
|
||||||
@ -2519,6 +2528,8 @@ v2.6.2 - Further bugfixes in Aztec and DotCode. Expand escape sequence support
|
|||||||
to API and GUI. Handle UTF BOM. Bugfix raster images of Maxicode.
|
to API and GUI. Handle UTF BOM. Bugfix raster images of Maxicode.
|
||||||
22/10/2017
|
22/10/2017
|
||||||
|
|
||||||
|
v2.6.3 - Includes VIN (US) verification. (Forthcoming)
|
||||||
|
|
||||||
7.4 Sources of Information
|
7.4 Sources of Information
|
||||||
--------------------------
|
--------------------------
|
||||||
Below is a list of some of the sources used in rough chronological order:
|
Below is a list of some of the sources used in rough chronological order:
|
||||||
|
@ -37,36 +37,37 @@
|
|||||||
|
|
||||||
/* Print list of supported symbologies */
|
/* Print list of supported symbologies */
|
||||||
void types(void) {
|
void types(void) {
|
||||||
printf( " 1: Code 11 50: Logmars 90: KIX Code\n"
|
printf( " 1: Code 11 51: Pharma One-Track 92: Aztec Code\n"
|
||||||
" 2: Standard 2of5 51: Pharma One-Track 92: Aztec Code\n"
|
" 2: Standard 2of5 52: PZN 93: DAFT Code\n"
|
||||||
" 3: Interleaved 2of5 52: PZN 93: DAFT Code\n"
|
" 3: Interleaved 2of5 53: Pharma Two-Track 97: Micro QR Code\n"
|
||||||
" 4: IATA 2of5 53: Pharma Two-Track 97: Micro QR Code\n"
|
" 4: IATA 2of5 55: PDF417 98: HIBC Code 128\n"
|
||||||
" 6: Data Logic 55: PDF417 98: HIBC Code 128\n"
|
" 6: Data Logic 56: PDF417 Trunc 99: HIBC Code 39\n"
|
||||||
" 7: Industrial 2of5 56: PDF417 Trunc 99: HIBC Code 39\n"
|
" 7: Industrial 2of5 57: Maxicode 102: HIBC Data Matrix\n"
|
||||||
" 8: Code 39 57: Maxicode 102: HIBC Data Matrix\n"
|
" 8: Code 39 58: QR Code 104: HIBC QR Code\n"
|
||||||
" 9: Extended Code 39 58: QR Code 104: HIBC QR Code\n"
|
" 9: Extended Code 39 60: Code 128-B 106: HIBC PDF417\n"
|
||||||
"13: EAN 60: Code 128-B 106: HIBC PDF417\n"
|
"13: EAN 63: AP Standard Customer 108: HIBC MicroPDF417\n"
|
||||||
"14: EAN + Check 63: AP Standard Customer 108: HIBC MicroPDF417\n"
|
"14: EAN + Check 66: AP Reply Paid 110: HIBC Codablock-F\n"
|
||||||
"16: GS1-128 66: AP Reply Paid 110: HIBC Codablock-F\n"
|
"16: GS1-128 67: AP Routing 112: HIBC Aztec Code\n"
|
||||||
"18: Codabar 67: AP Routing 112: HIBC Aztec Code\n"
|
"18: Codabar 68: AP Redirection 115: DotCode\n"
|
||||||
"20: Code 128 68: AP Redirection 115: DotCode\n"
|
"20: Code 128 69: ISBN 116: Han Xin Code\n"
|
||||||
"21: Leitcode 69: ISBN 116: Han Xin Code\n"
|
"21: Leitcode 70: RM4SCC 128: Aztec Runes\n"
|
||||||
"22: Identcode 70: RM4SCC 128: Aztec Runes\n"
|
"22: Identcode 71: Data Matrix 129: Code 32\n"
|
||||||
"23: Code 16k 71: Data Matrix 129: Code 32\n"
|
"23: Code 16k 72: EAN-14 130: Comp EAN\n"
|
||||||
"24: Code 49 72: EAN-14 130: Comp EAN\n"
|
"24: Code 49 73: VIN (North America) 131: Comp GS1-128\n"
|
||||||
"25: Code 93 74: Codablock-F 131: Comp GS1-128\n"
|
"25: Code 93 74: Codablock-F 132: Comp DataBar Omni\n"
|
||||||
"28: Flattermarken 75: NVE-18 132: Comp DataBar Omni\n"
|
"28: Flattermarken 75: NVE-18 133: Comp DataBar Ltd\n"
|
||||||
"29: GS1 DataBar Omni 76: Japanese Post 133: Comp DataBar Ltd\n"
|
"29: GS1 DataBar Omni 76: Japanese Post 134: Comp DataBar ExpOm\n"
|
||||||
"30: GS1 DataBar Ltd 77: Korea Post 134: Comp DataBar ExpOm\n"
|
"30: GS1 DataBar Ltd 77: Korea Post 135: Comp UPC-A\n"
|
||||||
"31: GS1 DataBar ExpOm 79: GS1 DataBar Stack 135: Comp UPC-A\n"
|
"31: GS1 DataBar ExpOm 79: GS1 DataBar Stack 136: Comp UPC-E\n"
|
||||||
"32: Telepen Alpha 80: GS1 DataBar Stack Omni 136: Comp UPC-E\n"
|
"32: Telepen Alpha 80: GS1 DataBar Stack Omni 137: Comp DataBar Stack\n"
|
||||||
"34: UPC-A 81: GS1 DataBar ESO 137: Comp DataBar Stack\n"
|
"34: UPC-A 81: GS1 DataBar ESO 138: Comp DataBar Stack Omni\n"
|
||||||
"35: UPC-A + Check 82: Planet 138: Comp DataBar Stack Omni\n"
|
"35: UPC-A + Check 82: Planet 139: Comp DataBar ESO\n"
|
||||||
"37: UPC-E 84: MicroPDF 139: Comp DataBar ESO\n"
|
"37: UPC-E 84: MicroPDF 140: Channel Code\n"
|
||||||
"38: UPC-E + Check 85: USPS OneCode 140: Channel Code\n"
|
"38: UPC-E + Check 85: USPS OneCode 141: Code One\n"
|
||||||
"40: Postnet 86: UK Plessey 141: Code One\n"
|
"40: Postnet 86: UK Plessey 142: Grid Matrix\n"
|
||||||
"47: MSI Plessey 87: Telepen Numeric 142: Grid Matrix\n"
|
"47: MSI Plessey 87: Telepen Numeric 143: UPNQR\n"
|
||||||
"49: FIM 89: ITF-14 143: UPNQR\n"
|
"49: FIM 89: ITF-14\n"
|
||||||
|
"50: Logmars 90: KIX Code\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user