#include #include #include #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 ) ); } } }