ref: 8485655705e7752e75716896ff96d25deaf9fa0c
author: Sigrid Haflínudóttir <[email protected]>
date: Sat Dec 28 08:16:46 EST 2019
add stuff
--- /dev/null
+++ b/LICENSE
@@ -1,0 +1,1 @@
+Public domain.
--- /dev/null
+++ b/README.md
@@ -1,0 +1,17 @@
+# hx
+
+A faster version of `hexdump -C` that I constantly use.
+
+Comparison on a 1.8Gb file, `time <command> >/dev/null`:
+
+| hexdump -C file | hx file |
+|:----------------|:---------------|
+| real 3m56.715s | real 0m6.111s |
+| user 3m55.839s | user 0m5.235s |
+| sus 0m0.847s | sys 0m0.489s |
+
+Around 40 times faster, eh?
+
+# Building
+
+`gcc -Wall -Wextra -O2 -s -g0 hx.c -o hx`
--- /dev/null
+++ b/hx.c
@@ -1,0 +1,163 @@
+#ifdef __linux__
+#define _GNU_SOURCE
+#else
+#define _DEFAULT_SOURCE
+#endif
+#define _FILE_OFFSET_BITS 64
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+enum
+{
+ Bufsz = 4*1024*1024,
+ Linesz = 87,
+};
+
+static unsigned char *buf;
+static const char b2h[] = (
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
+ "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
+ "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
+ "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
+ "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"
+ "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
+ "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
+ "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
+);
+
+static int
+hx(int fd)
+{
+ size_t addr;
+ ssize_t sz, i;
+ char s[65536], c;
+ unsigned char line[16];
+ int wroff, off, eof, wrlen, lineoff, r;
+
+#ifdef __linux__
+ readahead(fd, 0, Bufsz);
+#endif
+
+ lineoff = 0;
+ off = 0;
+ eof = 0;
+ for (addr = 0; eof == 0 && (sz = read(fd, buf, Bufsz)) > 0;) {
+ for (i = 0; i < sz; ) {
+ if (off >= (int)sizeof(s)-Linesz) {
+ wrlen = off - (off % Linesz);
+ for (wroff = 0; wroff < wrlen; wroff += r) {
+ if ((r = write(1, s+wroff, wrlen-wroff)) < 0) {
+ sz = -1;
+ break;
+ }
+ }
+ memmove(s, s+wrlen, off-wrlen);
+ off -= wrlen;
+ }
+
+ if (lineoff == 0) {
+ s[off++] = b2h[((addr>>55) & 0x1fe)];
+ s[off++] = b2h[((addr>>55) & 0x1fe)+1];
+ s[off++] = b2h[((addr>>47) & 0x1fe)];
+ s[off++] = b2h[((addr>>47) & 0x1fe)+1];
+ s[off++] = b2h[((addr>>39) & 0x1fe)];
+ s[off++] = b2h[((addr>>39) & 0x1fe)+1];
+ s[off++] = b2h[((addr>>31) & 0x1fe)];
+ s[off++] = b2h[((addr>>31) & 0x1fe)+1];
+ s[off++] = b2h[((addr>>23) & 0x1fe)];
+ s[off++] = b2h[((addr>>23) & 0x1fe)+1];
+ s[off++] = b2h[((addr>>15) & 0x1fe)];
+ s[off++] = b2h[((addr>>15) & 0x1fe)+1];
+ s[off++] = b2h[((addr>>7) & 0x1fe)];
+ s[off++] = b2h[((addr>>7) & 0x1fe)+1];
+ s[off++] = b2h[((addr<<1) & 0x1fe)];
+ s[off++] = b2h[((addr<<1) & 0x1fe)+1];
+ s[off++] = ' ';
+ s[off++] = ' ';
+ }
+
+ for (; i < sz && lineoff < 16; i++, addr++) {
+ if (lineoff < 16)
+ line[lineoff++] = buf[i];
+ s[off++] = b2h[(int)buf[i]*2+0];
+ s[off++] = b2h[(int)buf[i]*2+1];
+ s[off++] = ' ';
+ if (lineoff == 8)
+ s[off++] = ' ';
+ }
+
+ if (lineoff == 16) {
+asci:
+ s[off++] = ' ';
+ s[off++] = '|';
+ for (lineoff = 0; lineoff < 16; lineoff++) {
+ c = line[lineoff];
+ if (c < 0x20 || c > 0x7e)
+ c = '.';
+ s[off++] = c;
+ }
+ s[off++] = '|';
+ s[off++] = '\n';
+ lineoff = 0;
+ }
+ }
+
+#ifdef __linux__
+ readahead(fd, addr, Bufsz);
+#endif
+ }
+
+ if (sz >= 0) {
+ if (eof == 0 && lineoff > 0 && lineoff < 16) {
+ eof = 1;
+ for (; lineoff < 16; lineoff++) {
+ line[lineoff] = 0;
+ s[off++] = ' ';
+ s[off++] = ' ';
+ s[off++] = ' ';
+ }
+ i = sz = 0;
+ goto asci;
+ }
+ for (wroff = 0; wroff < off; wroff += r) {
+ if ((r = write(1, s+wroff, off-wroff)) < 0) {
+ sz = -1;
+ break;
+ }
+ }
+ }
+
+ return sz != 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int i, fd, res;
+
+ res = 0;
+
+ if ((buf = malloc(Bufsz)) == NULL) {
+ perror("buf");
+ res = 1;
+ }
+
+ for (i = 1; i < argc && res == 0; i++) {
+ if ((fd = open(argv[i], O_RDONLY)) < 0) {
+ perror(argv[i]);
+ res = 1;
+ } else {
+ if ((res = hx(fd)) != 0)
+ perror(argv[1]);
+ close(fd);
+ }
+ }
+
+ memset(buf, 0, Bufsz);
+ free(buf);
+
+ return res;
+}