hex

Hex stream reader / writer
git clone https://git.sinitax.com/sinitax/hex
Log | Files | Refs | LICENSE | sfeed.txt

unhex.c (1124B)


      1#include <unistd.h>
      2#include <fcntl.h>
      3#include <string.h>
      4#include <stdio.h>
      5#include <stdlib.h>
      6
      7const char *skip = " \t\r\n";
      8
      9char
     10hex2nib(char c, ssize_t *pos)
     11{
     12	switch (c) {
     13	case '0' ... '9':
     14		*pos += 1;
     15		return c - '0';
     16	case 'a' ... 'f':
     17		*pos += 1;
     18		return c - 'a' + 10;
     19	case 'A' ... 'F':
     20		*pos += 1;
     21		return c - 'A' + 10;
     22	}
     23
     24	if (!strchr(skip, c)) {
     25		fprintf(stderr, "Invalid hex '%c' at position %lu\n", c, *pos);
     26		exit(1);
     27	}
     28
     29	return 0;
     30}
     31
     32void
     33fromhex(int fd)
     34{
     35	ssize_t pos, i, nread;
     36	char buf[4096], nib;
     37
     38	pos = 0;
     39	while (1) {
     40		nread = read(fd, buf, sizeof(buf));
     41		if (nread <= 0) break;
     42
     43		for (i = 0; i < nread; i++) {
     44			if (pos % 2 == 0) {
     45				nib = hex2nib(buf[i], &pos);
     46			} else {
     47				putchar((nib << 4) | hex2nib(buf[i], &pos));
     48			}
     49		}
     50	}
     51
     52	if (pos % 2 != 0)
     53		putchar(nib << 4);
     54}
     55
     56int
     57main(int argc, const char **argv)
     58{
     59	int i, fd;
     60
     61	if (argc > 1) {
     62		for (i = 1; i < argc; i++) {
     63			fd = open(argv[i], O_RDONLY);
     64			if (fd < 0) {
     65				fprintf(stderr, "Could not open file: %s\n",
     66					argv[i]);
     67				continue;
     68			}
     69			fromhex(fd);
     70			close(fd);
     71		}
     72	} else {
     73		fromhex(0);
     74	}
     75}