GS1 Syntax Dictionary: Linter reference
A reference to the AI component linter routines referred to by the GS1 Syntax Dictionary. Copyright (c) 2022-2024 GS1 AISBL.
lint_csum.c File Reference

Purpose

The csum linter ensures that the data has a valid numeric check digit.

Remarks
The process for validating the standard GS1 numeric check digit is described in the GS1 General Specifications section "Standard check digit calculations for GS1 data structures".

Functional Description

◆ gs1_lint_csum()

GS1_SYNTAX_DICTIONARY_API gs1_lint_err_t gs1_lint_csum ( const char *const  data,
size_t *const  err_pos,
size_t *const  err_len 
)

Use to ensure that the AI component has a valid numeric check digit.

Parameters
[in]dataPointer to the null-terminated data to be linted. Must not be NULL.
[out]err_posTo facilitate error highlighting, the start position of the bad data is written to this pointer, if not NULL.
[out]err_lenThe length of the bad data is written to this pointer, if not NULL.
Returns
GS1_LINTER_OK if okay.
GS1_LINTER_INCORRECT_CHECK_DIGIT if the check digit is incorrect.
GS1_LINTER_TOO_SHORT_FOR_CHECK_DIGIT if the data is too short.
GS1_LINTER_NON_DIGIT_CHARACTER if the data contains a non-digit character.
56{
57
58 int weight;
59 int parity = 0;
60 const char *p;
61 size_t len, pos;
62
63 assert(data);
64
65 len = strlen(data);
66
67 /*
68 * Data must include at least the check digit.
69 *
70 */
71 if (*data == '\0') {
72 if (err_pos) *err_pos = 0;
73 if (err_len) *err_len = 0;
75 }
76
77 /*
78 * Data must consist of all digits.
79 *
80 */
81 if ((pos = strspn(data, "0123456789")) != len) {
82 if (err_pos) *err_pos = pos;
83 if (err_len) *err_len = 1;
85 }
86
87 /*
88 * Calculate the sum of the numeric values of the data, excluding the
89 * check digit, weighted by alternating ...3:1:3 values, from right to
90 * left.
91 *
92 * The check digit is valid if its value, when added to the data
93 * checksum, makes the overall sum a multiple of 10.
94 *
95 */
96 weight = len % 2 == 0 ? 3 : 1;
97 p = data;
98 while (*(p+1)) {
99 parity += weight * (*p++ - '0');
100 weight = 4 - weight;
101 }
102 parity = (10 - parity % 10) % 10;
103
104 if (parity + '0' != *p) {
105 if (err_pos) *err_pos = len - 1;
106 if (err_len) *err_len = 1;
108 }
109
110 return GS1_LINTER_OK;
111
112}
@ GS1_LINTER_TOO_SHORT_FOR_CHECK_DIGIT
The component is too short to perform a numeric check digit calculation.
Definition gs1syntaxdictionary.h:72
@ GS1_LINTER_INCORRECT_CHECK_DIGIT
The numeric check digit is incorrect.
Definition gs1syntaxdictionary.h:71
@ GS1_LINTER_OK
No issues were detected by the linter.
Definition gs1syntaxdictionary.h:66
@ GS1_LINTER_NON_DIGIT_CHARACTER
A non-digit character was found where a digit is expected.
Definition gs1syntaxdictionary.h:67