#include #include #include #include /* for CHAR_BIT */ unsigned long getbit8(unsigned char *b, /**< octet sequence */ unsigned pos, /**< 0 to 7 */ unsigned width) /**< 0 to 8 */ { unsigned mask; if (width == 0) { return 0; } else if (width == 1) { switch (pos) { case 0: return 1u & (b[0] >> 7); case 1: return 1u & (b[0] >> 6); case 2: return 1u & (b[0] >> 5); case 3: return 1u & (b[0] >> 4); case 4: return 1u & (b[0] >> 3); case 5: return 1u & (b[0] >> 2); case 6: return 1u & (b[0] >> 1); case 7: return 1u & (b[0] >> 0); } } else if (width == 2) { switch (pos) { case 0: return 3u & (b[0] >> 6); case 1: return 3u & (b[0] >> 5); case 2: return 3u & (b[0] >> 4); case 3: return 3u & (b[0] >> 3); case 4: return 3u & (b[0] >> 2); case 5: return 3u & (b[0] >> 1); case 6: return 3u & (b[0] >> 0); case 7: return 3u & (b[0] << 1 | b[1] >> 7); } } else if (width == 3) { switch (pos) { case 0: return 7u & (b[0] >> 5); case 1: return 7u & (b[0] >> 4); case 2: return 7u & (b[0] >> 3); case 3: return 7u & (b[0] >> 2); case 4: return 7u & (b[0] >> 1); case 5: return 7u & (b[0] >> 0); case 6: return 7u & (b[0] << 1 | b[1] >> 7); case 7: return 7u & (b[0] << 2 | b[1] >> 6); } } else if (width == 4) { switch (pos) { case 0: return 0xFu & (b[0] >> 4); case 1: return 0xFu & (b[0] >> 3); case 2: return 0xFu & (b[0] >> 2); case 3: return 0xFu & (b[0] >> 1); case 4: return 0xFu & (b[0] >> 0); case 5: return 0xFu & (b[0] << 1 | b[1] >> 7); case 6: return 0xFu & (b[0] << 2 | b[1] >> 6); case 7: return 0xFu & (b[0] << 3 | b[1] >> 5); } } else if (width == 5) { switch (pos) { case 0: return 0x1Fu & (b[0] >> 3); case 1: return 0x1Fu & (b[0] >> 2); case 2: return 0x1Fu & (b[0] >> 1); case 3: return 0x1Fu & (b[0] >> 0); case 4: return 0x1Fu & (b[0] << 1 | b[1] >> 7); case 5: return 0x1Fu & (b[0] << 2 | b[1] >> 6); case 6: return 0x1Fu & (b[0] << 3 | b[1] >> 5); case 7: return 0x1Fu & (b[0] << 4 | b[1] >> 4); } } else if (width == 6) { switch (pos) { case 0: return 0x1Fu & (b[0] >> 3); case 1: return 0x1Fu & (b[0] >> 2); case 2: return 0x1Fu & (b[0] >> 1); case 3: return 0x1Fu & (b[0] >> 0); case 4: return 0x1Fu & (b[0] << 1 | b[1] >> 7); case 5: return 0x1Fu & (b[0] << 2 | b[1] >> 6); case 6: return 0x1Fu & (b[0] << 3 | b[1] >> 5); case 7: return 0x1Fu & (b[0] << 4 | b[1] >> 4); } } else if (width == 5) { switch (pos) { case 0: return 0x1Fu & (b[0] >> 3); case 1: return 0x1Fu & (b[0] >> 2); case 2: return 0x1Fu & (b[0] >> 1); case 3: return 0x1Fu & (b[0] >> 0); case 4: return 0x1Fu & (b[0] << 1 | b[1] >> 7); case 5: return 0x1Fu & (b[0] << 2 | b[1] >> 6); case 6: return 0x1Fu & (b[0] << 3 | b[1] >> 5); case 7: return 0x1Fu & (b[0] << 4 | b[1] >> 4); } } else if (width == 5) { switch (pos) { case 0: return 0x1Fu & (b[0] >> 3); case 1: return 0x1Fu & (b[0] >> 2); case 2: return 0x1Fu & (b[0] >> 1); case 3: return 0x1Fu & (b[0] >> 0); case 4: return 0x1Fu & (b[0] << 1 | b[1] >> 7); case 5: return 0x1Fu & (b[0] << 2 | b[1] >> 6); case 6: return 0x1Fu & (b[0] << 3 | b[1] >> 5); case 7: return 0x1Fu & (b[0] << 4 | b[1] >> 4); } } /* error */ return 0xFF; } unsigned long getbits(unsigned char *buf, size_t pos, size_t width) { } int main(int argc, char **argv) { unsigned char *buf; unsigned long r; size_t pos, wid; unsigned i; if (argv[1] == NULL) goto help; pos = strtoul(argv[1], 0, 0); if (argv[2] == NULL) goto help; wid = strtoul(argv[2], 0, 0); buf = malloc(argc); if (buf == NULL) { perror("malloc"); return 1; } for (i = 3; argv[i]; i++) { buf[i - 3] = strtoul(argv[i], 0, 16); } r = getbits(buf, pos, wid); printf("%lx:%lx = %lx\n", (unsigned long)pos, (unsigned long)wid, r); return 0; help: puts("usage: z pos width hex2 ..."); return 1; }