GS1 Barcode Syntax Tests reference
A reference to the AI component "linter" routines referred to by the GS1 Barcode Syntax Dictionary. Copyright (c) 2022-2024 GS1 AISBL.
Macros
lint_iban.c File Reference

Macros

#define IBAN_MIN_LENGTH   10
 No clear minimum length; sufficient for check characters.
 
#define IBAN_MAX_LENGTH   34
 Per specification.
 

Purpose

The iban linter ensures that the data conforms to the format required for an International Bank Account Number (IBAN) number.

Remarks
The format for an IBAN is specified by ISO 13616-1: Financial services - International bank account number (IBAN) - Part 1: Structure of the IBAN.

Functional Description

◆ gs1_lint_iban()

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

Used to validate that an AI component conforms to the format required for an IBAN.

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_IBAN_CHECKSUM if the IBAN checksum is incorrect for the data.
GS1_LINTER_IBAN_TOO_SHORT if the data is too short to be an IBAN.
GS1_LINTER_IBAN_TOO_LONG if the data is too long to be an IBAN.
GS1_LINTER_INVALID_IBAN_CHARACTER if the data contains a character that isn't permissible within an IBAN.
GS1_LINTER_ILLEGAL_IBAN_COUNTRY_CODE if the leading two characters are not a valid ISO 3166 alpha-2 country code.
68{
69
70 char cc[3] = {0};
72 size_t len = 0, pos;
73 unsigned int csum = 0;
74 unsigned char weight;
75
76 /*
77 * IBAN character checksum weights (0 = invalid; weight off by 1)
78 *
79 */
80 static const unsigned char iban_weights[256] = {
81 ['0'] = 1, ['1'] = 2, ['2'] = 3, ['3'] = 4, ['4'] = 5,
82 ['5'] = 6, ['6'] = 7, ['7'] = 8, ['8'] = 9, ['9'] = 10,
83 ['A'] = 11, ['B'] = 12, ['C'] = 13, ['D'] = 14, ['E'] = 15,
84 ['F'] = 16, ['G'] = 17, ['H'] = 18, ['I'] = 19, ['J'] = 20,
85 ['K'] = 21, ['L'] = 22, ['M'] = 23, ['N'] = 24, ['O'] = 25,
86 ['P'] = 26, ['Q'] = 27, ['R'] = 28, ['S'] = 29, ['T'] = 30,
87 ['U'] = 31, ['V'] = 32, ['W'] = 33, ['X'] = 34, ['Y'] = 35, ['Z'] = 36
88 };
89
90 assert(data);
91
92 /*
93 * Require at least 4 characters before main loop
94 *
95 */
96 if (GS1_LINTER_UNLIKELY(!data[0] || !data[1] || !data[2] || !data[3]))
99 0,
100 strlen(data)
101 );
102
103 /*
104 * Validate the leading two-character country code
105 *
106 */
107 memcpy(cc, data, 2);
108 ret = gs1_lint_iso3166alpha2(cc, err_pos, err_len);
109 assert(ret == GS1_LINTER_OK || ret == GS1_LINTER_NOT_ISO3166_ALPHA2);
113 0,
114 2
115 );
116
117 pos = 4; /* Start at first data character after the check characters */
118 do {
120 while (data[pos]) pos++;
123 0,
124 pos
125 );
126 }
127
128 /*
129 * Wrap at end of data and record length
130 *
131 */
132 if (!data[pos]) {
136 0,
137 pos
138 );
139 len = pos;
140 pos = 0;
141 }
142
143 weight = iban_weights[(unsigned char)data[pos]];
144 if (GS1_LINTER_UNLIKELY(weight == 0))
147 pos,
148 1
149 );
150
151 csum *= weight <= 10 ? 10 : 100;
152 csum += weight - 1;
153 csum %= 97;
154 pos++;
155
156 } while (pos < 4 || len == 0); /* Until we wrap and pass the CC */
157
158 if (GS1_LINTER_UNLIKELY(csum != 1))
161 2,
162 2
163 );
164
166
167}
#define GS1_LINTER_UNLIKELY(x)
Implemention may provide hint to the compiler that the expression is likely to be false.
Definition gs1syntaxdictionary-utils.h:76
#define GS1_LINTER_RETURN_ERROR(error, position, length)
Return from a linter indicating that a problem was detected with the given data.
Definition gs1syntaxdictionary-utils.h:103
#define GS1_LINTER_RETURN_OK
Return from a linter indicating that no problem was detected with the given data.
Definition gs1syntaxdictionary-utils.h:88
GS1_SYNTAX_DICTIONARY_API gs1_lint_err_t gs1_lint_iso3166alpha2(const char *data, size_t *err_pos, size_t *err_len)
Definition lint_iso3166alpha2.c:75
gs1_lint_err_t
Linter return codes other than GS1_LINTER_OK indicate an error condition.
Definition gs1syntaxdictionary.h:76
@ GS1_LINTER_INCORRECT_IBAN_CHECKSUM
The IBAN is invalid since the check characters are incorrect.
Definition gs1syntaxdictionary.h:104
@ GS1_LINTER_INVALID_IBAN_CHARACTER
The IBAN contains an invalid character.
Definition gs1syntaxdictionary.h:102
@ GS1_LINTER_ILLEGAL_IBAN_COUNTRY_CODE
The IBAN must start with a valid ISO 3166 two-character country code.
Definition gs1syntaxdictionary.h:103
@ GS1_LINTER_IBAN_TOO_SHORT
The IBAN is too short.
Definition gs1syntaxdictionary.h:101
@ GS1_LINTER_OK
No issues were detected by the linter.
Definition gs1syntaxdictionary.h:77
@ GS1_LINTER_NOT_ISO3166_ALPHA2
A valid ISO 3166 two-character country code is required.
Definition gs1syntaxdictionary.h:99
@ GS1_LINTER_IBAN_TOO_LONG
The IBAN is too long.
Definition gs1syntaxdictionary.h:200
#define IBAN_MAX_LENGTH
Per specification.
Definition lint_iban.c:42
#define IBAN_MIN_LENGTH
No clear minimum length; sufficient for check characters.
Definition lint_iban.c:39