Georg Sauthoff nettle@gms.tf writes:
Hello,
On Mon, Apr 13, 2026 at 09:24:17AM +0200, Simon Josefsson wrote: [..]
hex_digits[16] = { '0', '1', '2', ... 'e', 'f' };
I'm hoping no compiler complains about missing ASCII NUL in a "string" defined that way.
The compilers available on gotbolt don't complain:
Great! I think that is a reasonable idiom, then.
Several base64 implementations use the last approach, but mostly for EBCDIC compatibility rather than to pacify false positive compiler warnings. Do Nettle care about EBCDIC targets? Gnulib's base64 code
FWIW, I would only worry about EBCDIC after somebody shows up who has a plausible use-case.
+1
IIRC that is what happened for gnulib base64 code, though, but it was a couple of years ago this change was made. Gnulib often goes to effort to be written in a portable way, because its applicability is beyond GNU/Linux. Maybe this isn't applicable to Nettle, but Nettle is a fairly low-level library so I wouldn't be surprised if it is running in EBCDIC environments.
has the snippet below, but it assumes 'char' is 8-bit.
I'm sorry, but this gnulib code is horrible.
Why are they over-using the c pre-processor like this ... I mean since gnulib is configure-time checking the world anyway they could simply detect EBCDIC at configure time and conditonally guard/include full ASCII/EBCDIC arrays based on that result.
That would be unreliable for cross-compilation.
Or even generating the array in M4 or some ultra-portable form of shell at configure time would be a more sensible approach than this.
I'd say the current C code is relatively straight-forward, solves the problem, and compilers end up optimizing it properly anyway. Introducing a pre-processing step seems complicated to me.
I'm not disagreeing that the code is horrible, but I'm not aware of any reliable idiom that solves the requirements in a better way.
/Simon
#define B64(_) \ ((_) == 'A' ? 0 \ : (_) == 'B' ? 1 \ : (_) == 'C' ? 2 \ : (_) == 'D' ? 3 \ ... : (_) == '8' ? 60 \ : (_) == '9' ? 61 \ : (_) == '+' ? 62 \ : (_) == '/' ? 63 \ : -1)
signed char const base64_to_int[256] = { B64 (0), B64 (1), B64 (2), B64 (3), ... B64 (252), B64 (253), B64 (254), B64 (255) };
Best regards, Georg