pub fn printBytes(bytes: []const u8) void {
    std.debug.print("Length: {}", .{bytes.len});
    for (0..bytes.len / 16 + 1) |row| {
        std.debug.print("\n{x:0>8}  ", .{row * 16});
        const end = @min(bytes.len, row * 16 + 16);
        const section = bytes[row * 16 .. end];

        for (section) |b| {
            std.debug.print("{x:0>2} ", .{b});
        }

        const remaining = 16 - section.len;
        if (remaining > 0) {
            std.debug.print("EOF", .{});
            for (0..remaining - 1) |_| {
                std.debug.print("   ", .{});
            }
        }

        std.debug.print("|", .{});
        for (section) |b| {
            if (b == ' ' or (std.ascii.isPrint(b) and !std.ascii.isWhitespace(b))) {
                std.debug.print("{c}", .{b});
            } else {
                std.debug.print(".", .{});
            }
        }
        std.debug.print("|", .{});
    }
    std.debug.print("\n", .{});
}