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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user