|
1 | 1 | #include <assert.h>
|
2 | 2 | #include <inttypes.h>
|
3 | 3 | #include <stdbool.h>
|
| 4 | +#include <stddef.h> |
4 | 5 | #include <stdio.h>
|
5 | 6 | #include <stdlib.h>
|
6 | 7 | #include <string.h>
|
@@ -136,54 +137,21 @@ int const R[16] =
|
136 | 137 | /******************************************************************************
|
137 | 138 | * Parse a string into number.
|
138 | 139 | *
|
139 |
| - * @param str String. |
| 140 | + * @param str String containing hexadecimal digits. |
140 | 141 | *
|
141 |
| - * @return Number represented by at most 16 rightmost characters of the string |
142 |
| - * if the entire string contains only hexadecimal digits, else 0. |
| 142 | + * @return Number represented by the last 16 characters of the string if the |
| 143 | + * said characters are all hexadecimal, else 0. |
143 | 144 | *****************************************************************************/
|
144 | 145 | uint64_t parse_hexadecimal(char const *str)
|
145 | 146 | {
|
146 |
| - uint64_t val = 0; |
147 |
| - while(*str != '\0') |
| 147 | + size_t len = strlen(str); |
| 148 | + if(len > 16) |
148 | 149 | {
|
149 |
| - int unsigned nibble; |
150 |
| - switch(*str) |
151 |
| - { |
152 |
| - case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': |
153 |
| - nibble = *str - '0'; |
154 |
| - break; |
155 |
| - |
156 |
| - case 'A': case 'a': |
157 |
| - nibble = 10; |
158 |
| - break; |
159 |
| - |
160 |
| - case 'B': case 'b': |
161 |
| - nibble = 11; |
162 |
| - break; |
163 |
| - |
164 |
| - case 'C': case 'c': |
165 |
| - nibble = 12; |
166 |
| - break; |
167 |
| - |
168 |
| - case 'D': case 'd': |
169 |
| - nibble = 13; |
170 |
| - break; |
171 |
| - |
172 |
| - case 'E': case 'e': |
173 |
| - nibble = 14; |
174 |
| - break; |
175 |
| - |
176 |
| - case 'F': case 'f': |
177 |
| - nibble = 15; |
178 |
| - break; |
179 |
| - |
180 |
| - default: |
181 |
| - return 0; |
182 |
| - } |
183 |
| - val = val << 4 | nibble; |
184 |
| - ++str; |
| 150 | + str += len - 16; |
185 | 151 | }
|
186 |
| - return val; |
| 152 | + char *endptr; |
| 153 | + uint64_t val = strtoull(str, &endptr, 16); |
| 154 | + return *endptr == '\0' ? val : 0; |
187 | 155 | }
|
188 | 156 |
|
189 | 157 | /******************************************************************************
|
@@ -378,9 +346,9 @@ int main(int const argc, char const *argv[])
|
378 | 346 | return EXIT_SUCCESS;
|
379 | 347 | }
|
380 | 348 |
|
381 |
| - uint64_t key = argc >= 2 ? parse_hexadecimal(argv[1]) : 0; |
382 |
| - uint64_t state = argc >= 3 ? parse_hexadecimal(argv[2]) : 0; |
383 |
| - if(argc >= 4 && strcmp(argv[3], "decrypt") == 0) |
| 349 | + uint64_t key = argc > 1 ? parse_hexadecimal(argv[1]) : 0; |
| 350 | + uint64_t state = argc > 2 ? parse_hexadecimal(argv[2]) : 0; |
| 351 | + if(argc > 3 && strcmp(argv[3], "decrypt") == 0) |
384 | 352 | {
|
385 | 353 | des_demo(key, state, false);
|
386 | 354 | }
|
|
0 commit comments