summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReepca Russelstein <reepca@russelstein.xyz>2026-06-21 07:13:16 -0500
committerLudovic Courtès <ludo@gnu.org>2026-06-24 15:20:16 +0200
commit64a0824955aa40ea8e59bd4328ecaaf8caaa2acc (patch)
tree1cdc5cc39fa2f8da5f8d568c961c22683505e4e8
parent938c3c5619d4543b24e12c6556e0ce4309ed242b (diff)
daemon: libutil: add base32Values and use them.
Recognizing base32 characters and/or parsing them into byte sequences is done in several places, so it makes sense to provide a common lookup table. * nix/libutil/hash.hh (base32Values, base32ValuesInitialized): new variables. (initializeBase32Values, getBase32Value): new functions. * nix/libutil/hash.cc (base32Values, base32ValuesInitialized): provide definition for variables. (initializeBase32Values, getBase32Value): provide function implementations. (parseHash32): use base32Values. * nix/libstore/references.cc (search): use base32Values. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
-rw-r--r--nix/libstore/references.cc11
-rw-r--r--nix/libutil/hash.cc19
-rw-r--r--nix/libutil/hash.hh3
3 files changed, 19 insertions, 14 deletions
diff --git a/nix/libstore/references.cc b/nix/libstore/references.cc
index a8ec39ee34b..20b55db6abc 100644
--- a/nix/libstore/references.cc
+++ b/nix/libstore/references.cc
@@ -17,20 +17,11 @@ static unsigned int refLength = 32; /* characters */
17static void search(const unsigned char * s, unsigned int len, 17static void search(const unsigned char * s, unsigned int len,
18 StringSet & hashes, StringSet & seen) 18 StringSet & hashes, StringSet & seen)
19{ 19{
20 static bool initialised = false;
21 static bool isBase32[256];
22 if (!initialised) {
23 for (unsigned int i = 0; i < 256; ++i) isBase32[i] = false;
24 for (unsigned int i = 0; i < base32Chars.size(); ++i)
25 isBase32[(unsigned char) base32Chars[i]] = true;
26 initialised = true;
27 }
28
29 for (unsigned int i = 0; i + refLength <= len; ) { 20 for (unsigned int i = 0; i + refLength <= len; ) {
30 int j; 21 int j;
31 bool match = true; 22 bool match = true;
32 for (j = refLength - 1; j >= 0; --j) 23 for (j = refLength - 1; j >= 0; --j)
33 if (!isBase32[(unsigned char) s[i + j]]) { 24 if (base32Values[(unsigned char) s[i + j]] == -1) {
34 i += j + 1; 25 i += j + 1;
35 match = false; 26 match = false;
36 break; 27 break;
diff --git a/nix/libutil/hash.cc b/nix/libutil/hash.cc
index ac9eb14514b..06753d19619 100644
--- a/nix/libutil/hash.cc
+++ b/nix/libutil/hash.cc
@@ -17,6 +17,18 @@
17 17
18namespace nix { 18namespace nix {
19 19
20static std::vector<char> getBase32Values()
21{
22 assert(base32Chars.size() <= std::numeric_limits<unsigned char>::max()+1);
23 assert(base32Chars.size() <= std::numeric_limits<char>::max()+1);
24 std::vector<char> values(std::numeric_limits<unsigned char>::max()+1, -1);
25 for (string::size_type j = 0; j < base32Chars.size(); j++)
26 values[(unsigned char) base32Chars[j]] = (char) j;
27 return values;
28}
29
30const std::vector<char> base32Values = getBase32Values();
31
20 32
21Hash::Hash() 33Hash::Hash()
22{ 34{
@@ -139,11 +151,10 @@ Hash parseHash32(HashType ht, std::string_view s)
139 151
140 for (unsigned int n = 0; n < len; ++n) { 152 for (unsigned int n = 0; n < len; ++n) {
141 char c = s[len - n - 1]; 153 char c = s[len - n - 1];
142 unsigned char digit; 154 char sdigit = base32Values[(unsigned char) c];
143 for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */ 155 if (sdigit < 0)
144 if (base32Chars[digit] == c) break;
145 if (digit >= 32)
146 throw Error(std::format("invalid base-32 hash '{}'", s)); 156 throw Error(std::format("invalid base-32 hash '{}'", s));
157 unsigned char digit = (unsigned char) sdigit;
147 unsigned int b = n * 5; 158 unsigned int b = n * 5;
148 unsigned int i = b / 8; 159 unsigned int i = b / 8;
149 unsigned int j = b % 8; 160 unsigned int j = b % 8;
diff --git a/nix/libutil/hash.hh b/nix/libutil/hash.hh
index cedb5077c16..fabe50c11c6 100644
--- a/nix/libutil/hash.hh
+++ b/nix/libutil/hash.hh
@@ -1,6 +1,7 @@
1#pragma once 1#pragma once
2 2
3#include <gcrypt.h> 3#include <gcrypt.h>
4#include <limits>
4 5
5#include "archive.hh" 6#include "archive.hh"
6#include "types.hh" 7#include "types.hh"
@@ -11,6 +12,8 @@ namespace nix {
11 12
12// omitted: E O U T 13// omitted: E O U T
13inline const string base32Chars {"0123456789abcdfghijklmnpqrsvwxyz"}; 14inline const string base32Chars {"0123456789abcdfghijklmnpqrsvwxyz"};
15/* Maps character to value, or -1 if not part of base32 character set. */
16extern const std::vector<char> base32Values;
14 17
15typedef enum { 18typedef enum {
16 htUnknown = 0, 19 htUnknown = 0,