Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : * Copyright (c) 2013-2017 Nest Labs, Inc.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * This file implements an object for Verhoeff's check-digit
22 : * algorithm for base-10 strings.
23 : *
24 : */
25 :
26 : #include "Verhoeff.h"
27 :
28 : #include <stdint.h>
29 : #include <string.h>
30 :
31 : #ifndef VERHOEFF10_NO_MULTIPLY_TABLE
32 :
33 : const uint8_t Verhoeff10::sMultiplyTable[] = {
34 : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 0, 6, 7, 8, 9, 5, 2, 3, 4, 0, 1, 7, 8, 9, 5, 6, 3, 4, 0, 1,
35 : 2, 8, 9, 5, 6, 7, 4, 0, 1, 2, 3, 9, 5, 6, 7, 8, 5, 9, 8, 7, 6, 0, 4, 3, 2, 1, 6, 5, 9, 8, 7, 1, 0, 4,
36 : 3, 2, 7, 6, 5, 9, 8, 2, 1, 0, 4, 3, 8, 7, 6, 5, 9, 3, 2, 1, 0, 4, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
37 : };
38 :
39 : #endif
40 :
41 : const uint8_t Verhoeff10::sPermTable[] = { 1, 5, 7, 6, 2, 8, 3, 0, 9, 4 };
42 :
43 38 : char Verhoeff10::ComputeCheckChar(const char * str)
44 : {
45 38 : return ComputeCheckChar(str, strlen(str));
46 : }
47 :
48 64 : char Verhoeff10::ComputeCheckChar(const char * str, size_t strLen)
49 : {
50 64 : int c = 0;
51 :
52 972 : for (size_t i = 1; i <= strLen; i++)
53 : {
54 910 : char ch = str[strLen - i];
55 :
56 910 : int val = CharToVal(ch);
57 910 : if (val < 0)
58 2 : return 0; // invalid character
59 :
60 908 : int p = Verhoeff::Permute(val, sPermTable, Base, i);
61 :
62 : #ifdef VERHOEFF10_NO_MULTIPLY_TABLE
63 : c = Verhoeff::DihedralMultiply(c, p, PolygonSize);
64 : #else
65 908 : c = sMultiplyTable[c * Base + p];
66 : #endif
67 : }
68 :
69 62 : c = Verhoeff::DihedralInvert(c, PolygonSize);
70 :
71 62 : return ValToChar(c);
72 : }
73 :
74 26 : bool Verhoeff10::ValidateCheckChar(char checkChar, const char * str)
75 : {
76 26 : return ValidateCheckChar(checkChar, str, strlen(str));
77 : }
78 :
79 26 : bool Verhoeff10::ValidateCheckChar(char checkChar, const char * str, size_t strLen)
80 : {
81 26 : return (ComputeCheckChar(str, strLen) == checkChar);
82 : }
83 :
84 0 : bool Verhoeff10::ValidateCheckChar(const char * str)
85 : {
86 0 : return ValidateCheckChar(str, strlen(str));
87 : }
88 :
89 0 : bool Verhoeff10::ValidateCheckChar(const char * str, size_t strLen)
90 : {
91 0 : if (strLen == 0)
92 0 : return false;
93 0 : return ValidateCheckChar(str[strLen - 1], str, strLen - 1);
94 : }
95 :
96 922 : int Verhoeff10::CharToVal(char ch)
97 : {
98 922 : if (ch >= '0' && ch <= '9')
99 920 : return ch - '0';
100 2 : return -1;
101 : }
102 :
103 62 : char Verhoeff10::ValToChar(int val)
104 : {
105 62 : if (val >= 0 && val <= Base)
106 62 : return static_cast<char>('0' + val);
107 0 : return 0;
108 : }
|