| ... | ... | @@ -123,3 +123,25 @@ const BufBiterator = struct { |
| 123 | 123 | return @intFromBool(result); |
| 124 | 124 | } |
| 125 | 125 | }; |
| 126 | |
| 127 | pub fn decodeBase32(input: []const u8, Hash: type) ![Hash.digest_length]u8 { |
| 128 | var result: std.bit_set.ArrayBitSet(u8, Hash.digest_length * 8) = .initEmpty(); |
| 129 | const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; |
| 130 | for (input, 0..) |c, i| { |
| 131 | const x = std.mem.indexOfScalar(u8, alphabet, c) orelse return error.InvalidCharacter; |
| 132 | const n: u5 = @intCast(x); |
| 133 | inline for (0..5) |j| blk: { |
| 134 | if (i * 5 > result.capacity()) return error.Overflow; |
| 135 | const d = i * 5 + j; |
| 136 | if (d >= result.capacity()) break :blk; |
| 137 | result.setValue(d, n & (1 << 5 - 1 - (j)) != 0); |
| 138 | } |
| 139 | } |
| 140 | return bitReverse(result.masks); |
| 141 | } |
| 142 | |
| 143 | fn bitReverse(array: anytype) [array.len]std.meta.Child(@TypeOf(array)) { |
| 144 | var result: [array.len]std.meta.Child(@TypeOf(array)) = @splat(0); |
| 145 | for (&array, &result) |x, *y| y.* = @bitReverse(x); |
| 146 | return result; |
| 147 | } |