Skip to content

Instantly share code, notes, and snippets.

@KaneRoot
Forked from vmolsa/hexdump.zig
Last active January 19, 2023 16:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KaneRoot/caa34cba0a317fb6f96d3a4f93b1e228 to your computer and use it in GitHub Desktop.
Save KaneRoot/caa34cba0a317fb6f96d3a4f93b1e228 to your computer and use it in GitHub Desktop.
Hexdump written in zig
// Example: try hexdump(std.io.getStdOut().writer(), "Hello World", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
//
// Hello World
//
// 0000: 4C 6F 72 65 6D 20 69 70 73 75 6D 20 64 6F 6C 6F Lorem ipsum dolo
// 0016: 72 20 73 69 74 20 61 6D 65 74 2C 20 63 6F 6E 73 r sit amet, cons
// 0032: 65 63 74 65 74 75 72 20 61 64 69 70 69 73 63 69 ectetur adipisci
// 0048: 6E 67 20 65 6C 69 74 2C 20 73 65 64 20 64 6F 20 ng elit, sed do
// 0064: 65 69 75 73 6D 6F 64 20 74 65 6D 70 6F 72 20 69 eiusmod tempor i
// 0080: 6E 63 69 64 69 64 75 6E 74 20 75 74 20 6C 61 62 ncididunt ut lab
// 0096: 6F 72 65 20 65 74 20 64 6F 6C 6F 72 65 20 6D 61 ore et dolore ma
// 0112: 67 6E 61 20 61 6C 69 71 75 61 2E 20 55 74 20 65 gna aliqua. Ut e
// 0128: 6E 69 6D 20 61 64 20 6D 69 6E 69 6D 20 76 65 6E nim ad minim ven
// 0144: 69 61 6D 2C 20 71 75 69 73 20 6E 6F 73 74 72 75 iam, quis nostru
// 0160: 64 20 65 78 65 72 63 69 74 61 74 69 6F 6E 20 75 d exercitation u
// 0176: 6C 6C 61 6D 63 6F 20 6C 61 62 6F 72 69 73 20 6E llamco laboris n
// 0192: 69 73 69 20 75 74 20 61 6C 69 71 75 69 70 20 65 isi ut aliquip e
// 0208: 78 20 65 61 20 63 6F 6D 6D 6F 64 6F 20 63 6F 6E x ea commodo con
// 0224: 73 65 71 75 61 74 2E 20 44 75 69 73 20 61 75 74 sequat. Duis aut
// 0240: 65 20 69 72 75 72 65 20 64 6F 6C 6F 72 20 69 6E e irure dolor in
// 0256: 20 72 65 70 72 65 68 65 6E 64 65 72 69 74 20 69 reprehenderit i
// 0272: 6E 20 76 6F 6C 75 70 74 61 74 65 20 76 65 6C 69 n voluptate veli
// 0288: 74 20 65 73 73 65 20 63 69 6C 6C 75 6D 20 64 6F t esse cillum do
// 0304: 6C 6F 72 65 20 65 75 20 66 75 67 69 61 74 20 6E lore eu fugiat n
// 0320: 75 6C 6C 61 20 70 61 72 69 61 74 75 72 2E 20 45 ulla pariatur. E
// 0336: 78 63 65 70 74 65 75 72 20 73 69 6E 74 20 6F 63 xcepteur sint oc
// 0352: 63 61 65 63 61 74 20 63 75 70 69 64 61 74 61 74 caecat cupidatat
// 0368: 20 6E 6F 6E 20 70 72 6F 69 64 65 6E 74 2C 20 73 non proident, s
// 0384: 75 6E 74 20 69 6E 20 63 75 6C 70 61 20 71 75 69 unt in culpa qui
// 0400: 20 6F 66 66 69 63 69 61 20 64 65 73 65 72 75 6E officia deserun
// 0416: 74 20 6D 6F 6C 6C 69 74 20 61 6E 69 6D 20 69 64 t mollit anim id
// 0432: 20 65 73 74 20 6C 61 62 6F 72 75 6D 2E est laborum.
//
const std = @import("std");
pub fn hexdump(stream: anytype, header: [] const u8, buffer: [] const u8) std.os.WriteError!void {
// Print a header.
if (header.len > 0) {
var hdr: [64] u8 = undefined;
var offset: usize = (hdr.len / 2) - ((header.len / 2) - 1);
std.mem.set(u8, hdr[0..hdr.len], ' ');
std.mem.copy(u8, hdr[offset..hdr.len], header);
try stream.writeAll(hdr[0..hdr.len]);
try stream.writeAll("\n");
}
var hexb: u32 = 0;
var ascii: [16] u8 = undefined;
// First line, first left side (simple number).
try stream.print("\n {d:0>4}: ", .{ hexb });
// Loop on all values in the buffer (i from 0 to buffer.len).
var i: u32 = 0;
while (i < buffer.len) : (i += 1) {
// Print actual hexadecimal value.
try stream.print("{X:0>2} ", .{ buffer[i] });
// What to print (simple ascii text, right side).
if (buffer[i] >= ' ' and buffer[i] <= '~') {
ascii[(i % 16)] = buffer[i];
} else {
ascii[(i % 16)] = '.';
}
// Next input is a multiple of 8 = extra space.
if ((i + 1) % 8 == 0) {
try stream.writeAll(" ");
}
// No next input: print the right amount of spaces.
if ((i + 1) == buffer.len) {
// Each line is 16 bytes to print, each byte takes 3 characters.
var missing_spaces = 3 * (15 - (i%16));
// Missing an extra space if the current index % 16 is less than 7.
if ((i%16) < 7) { missing_spaces += 1; }
while (missing_spaces > 0) : (missing_spaces -= 1) {
try stream.writeAll(" ");
}
}
// Every 16 bytes: print ascii text and line return.
// Case 1: it's been 16 bytes AND it's the last byte to print.
if ((i + 1) % 16 == 0 and (i + 1) == buffer.len) {
try stream.print("{s}\n", .{ ascii[0..ascii.len] });
}
// Case 2: it's been 16 bytes but it's not the end of the buffer.
else if ((i + 1) % 16 == 0 and (i + 1) != buffer.len) {
try stream.print("{s}\n", .{ ascii[0..ascii.len] });
hexb += 16;
try stream.print(" {d:0>4}: ", .{ hexb });
}
// Case 3: not the end of the 16 bytes row but it's the end of the buffer.
else if ((i + 1) % 16 != 0 and (i + 1) == buffer.len) {
try stream.print(" {s}\n", .{ ascii[0..((i+1) % 16)] });
}
// Case 4: not the end of the 16 bytes row and not the end of the buffer.
// Do nothing.
}
try stream.writeAll("\n");
}
test "hello this is a test" {
try hexdump(std.io.getStdOut().writer(), "Hello World", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
}
@KaneRoot
Copy link
Author

This version prints all characters and shouldn't miss spaces.
In previous version, last byte was missing.
Also, spaces on the last row weren't handled correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment