code:
const std = @import("std");
pub const Error = error{ WrongCode };
pub fn Base16(comptime map: *const [16]u8) type {
return struct {
pub fn calcSize(len: usize) usize {
return len * 2;
}
pub fn encode(dst: []u8, src: []const u8) void {
if (dst.len != calcSize(src.len)) @panic("length mismatch");
for (src) |ch, i| {
std.log.err(":{x}:{}{}", .{ch, [1]u8{map[(@intCast(usize, ch) >> 4) % 0xF]}, [1]u8{map[@intCast(usize, ch) % 0xF]}});
dst[i * 2] = map[(@intCast(usize, ch) >> 4) % 0xF];
dst[i * 2 + 1] = map[@intCast(usize, ch) % 0xF];
}
}
fn getOrigin(ch: u8) ?u8 {
inline for (map) |x, i| {
if (x == ch) return @intCast(u8, i);
}
return null;
}
pub fn decode(dst: []u8, src: []const u8) Error!void {
if (src.len != calcSize(dst.len)) @panic("length mismatch");
var rch: u8 = undefined;
for (src) |ch, i| {
const origin = getOrigin(ch) orelse return Error.WrongCode;
if (i % 2 == 0) {
rch = origin << 4;
} else {
rch |= origin;
}
}
}
};
}
const standard_base16 = Base16("0123456789ABCDEF");
test "encode" {
var dst: [8]u8 = undefined;
standard_base16.encode(&dst, "0123");
std.log.err("{}", .{dst});
std.testing.expectEqual(@as(*const [8]u8, &dst).*, "30313233".*);
}
PS: I know there is a mistake in % 0xF (it should be % 0x10)
code:
PS: I know there is a mistake in
% 0xF(it should be % 0x10)