1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define UPC_A_WIDTH 95
#define UPC_A_NUMDIGITS 12
const char UPC_A_GUARD_PATTERN_SE[3] = { 1, 0, 1 };
const char UPC_A_GUARD_PATTERN_M[5] = { 0, 1, 0, 1, 0 };
const char UPC_DIGIT[10][7] = { { 0, 0, 0, 1, 1, 0, 1 },
{ 0, 0, 1, 1, 0, 0, 1 },
{ 0, 0, 1, 0, 0, 1, 1 },
{ 0, 1, 1, 1, 1, 0, 1 },
{ 0, 1, 0, 0, 0, 1, 1 },
{ 0, 1, 1, 0, 0, 0, 1 },
{ 0, 1, 0, 1, 1, 1, 1 },
{ 0, 1, 1, 1, 0, 1, 1 },
{ 0, 1, 1, 0, 1, 1, 1 },
{ 0, 0, 0, 1, 0, 1, 1 } };
static char upc_calculate_check_digit( char *digits );
static void upc_draw_pattern( char buffer[], int *index, const char *pattern, int pattern_size );
static void upc_draw_digits( char *buffer, int *index, char *digits, char isLeft );
const char* create_upc_a( char *input ) {
// allocate 95 bytes of memory for resultant data
char *result = malloc(UPC_A_WIDTH);
// create a char array to store the GTIN-12 number
char digits[UPC_A_NUMDIGITS];
int index = 0;
// copy digits from function param to local array
memcpy( digits, input, UPC_A_NUMDIGITS );
// set the final digit to the appropriate check digit
// digits[11] = upc_calculate_check_digit( digits );
// draw start guard pattern
upc_draw_pattern( result, &index, UPC_A_GUARD_PATTERN_SE, sizeof(UPC_A_GUARD_PATTERN_SE) );
// draw LLLLLL digits
upc_draw_digits( result, &index, digits, 1 );
// draw middle guard pattern
upc_draw_pattern( result, &index, UPC_A_GUARD_PATTERN_M, sizeof(UPC_A_GUARD_PATTERN_M) );
// draw RRRRRR digits
upc_draw_digits( result, &index, digits, 0 );
// draw end guard pattern
upc_draw_pattern( result, &index, UPC_A_GUARD_PATTERN_SE, sizeof(UPC_A_GUARD_PATTERN_SE) );
return result;
}
char upc_a_calculate_check_digit( char *digits ) {
char result = 0;
int M;
// 1. Sum digits at odd-numbered positions
for( int i = 0; i < UPC_A_NUMDIGITS; ++i ) {
if( i % 2 == 0 ) { result += digits[i]; }
}
// 2. Multiply result by 3
result *= 3;
// 3. Add digits at even-numbered positions to the result
for( int i = 0; i < UPC_A_NUMDIGITS; ++i ) {
if( i % 2 != 0 ) { result += digits[i]; }
}
// 4. Find the result mod 10 and call it "M"
M = result % 10;
// 5. If M is zero, the check digit is 0,
if( M == 0 ) { result = M; }
// otherwise the check digit is 10 - M
else {
result = 10 - M;
}
return result;
}
static void upc_draw_pattern( char buffer[], int *index, const char *pattern, int pattern_size ) {
for( int i = 0; i < pattern_size; ++i ) {
buffer[*index] = pattern[i];
++*index;
}
}
static void upc_draw_digits( char *buffer, int *index, char *digits, char isLeft ) {
char temp[6][7];
if ( isLeft ) {
for( int i = 0; i < 6; ++i ) {
memcpy(temp[i], UPC_DIGIT[digits[i]], sizeof( *UPC_DIGIT ) );
upc_draw_pattern( buffer, index, temp[i], sizeof( *UPC_DIGIT ) );
}
}
else {
for( int i = 0; i < 6; ++i ) {
memcpy(temp[i], UPC_DIGIT[digits[i + 6]], sizeof( *UPC_DIGIT ) );
//invert values of RRRRRR digits
for( int j = 0; j < sizeof( *UPC_DIGIT ); ++j ) {
temp[i][j] = !temp[i][j];
}
upc_draw_pattern( buffer, index, temp[i], sizeof( *UPC_DIGIT ) );
}
}
}
|