Hex

在版本 6 Unix 中取消轉儲 od(八進製或十六進制轉儲)

  • July 7, 2019

od(八進制轉儲)命令自版本 1 起在 Unix 中實現。但是,我在版本 6 Unix 手冊(1975 年)中找不到反向命令。現代的逆轉od方法不適用於 Unix V6,因為and只出現在版本 7 中(而, 和都不xxd可用)。sed``sed``awk``uudecode``xxd``base64

問題是:

  • 1975 年的人們如何將八進製或十六進制列表轉換為二進製文件?
  • 如何在僅允許我將文本從剪貼板粘貼到終端的 PDP-11 模擬器中執行此操作?(換句話說,有必要為此編寫我自己的程序嗎?)

這是一個二進製文件的範例十六進制轉儲od,我想將其轉換回二進製文件:

# od -h /bin/sum
0000000 0107 00ba 0000 0204 0000 0000 0000 0001
0000020 1583 0bd6 0ac3 0601 8901 0a37 00ae 15b7
0000040 0002 8905 0000 0000 8609 15c0 0001 8904
0000060 0026 0005 01ef 706f 6472 000a 1001 0a05
0000100 1040 8903 00be 0200 870b 0bc0 030e 0ab7
0000120 007a 15c2 00be 9484 6105 0b45 7e04 01f0
0000140 15c0 0001 8904 0080 0002 09f7 0026 15c0
0000160 0001 8904 0083 0001 1dc5 0050 09f7 0014
0000200 15c0 0001 8904 0082 0001 1040 8906 01c2
0000220 203f 200a 1026 1066 1141 09f7 0006 1581
0000240 1580 0087 0a00 7217 000a 1066 1001 0302
0000260 09f7 fff0 15b7 0012 65f7 0030 000c 15c0
0000300 0001 8904 00ba 0001 0087
0000312 

看起來 Unix 版本 6 還沒有包含許多只出現在版本 7 中的常用工具(如sedawk)。那時,Unix 還沒有商業化,所以“反向十六進制轉儲”可能會失去,這僅僅是因為對該操作沒有廣泛的需求,或者因為 Ken(或其他一些程序員)從他們/usr在貝爾實驗室的非官方目錄中提供了這樣的工具。誰知道。

但這是我在 Unix V6 上反轉十六進制轉儲的實現。當像 一樣編譯時cc -s -O unhex.c,生成的執行檔只有 1160 字節,並且比轉儲更快(如預期的那樣)。

請注意當時的 C 語言如何仍然具有 B ( , 等) 的複合賦值語法,=+以及=*它如何期望程序員為文件 I/O 提供自己的緩衝區。

/* reverse "od -h" operation on Unix V6 */
/* written in pre-K&R C */
/* derived from wc.c and cvopt.c */

int ibuf[259];
int obuf[259];

main(argc,argv)
char **argv;
{
   int token, bytecnt;
   register char *p1, *p2;         /* input buffer pointers */
   register int c;                 /* char or read count */
   char sp, b1, b2, lastc, lastb2, nfirst;

   obuf[0] = 1;                    /* standard output by default */
   if (argc>2) {
                                   /* create output file */
           if ((obuf[0] = creat(argv[2], 0666)) < 0) {
                   diag(argv[2]);
                   diag(": failed to create\n");
                   return;
           }
   }
   if (argc>1 && fopen(argv[1], ibuf)>=0) {
           p1 = 0;
           p2 = 0;
           sp = 0;
           token = 0;
           bytecnt = 0;
           nfirst = 0;
           for(;;) {
                   /* reading from file */
                   if (p1 >= p2) {
                           p1 = &ibuf[1];
                           c = read(ibuf[0], p1, 512);
                           if (c <= 0)
                                   break;
                           p2 = p1+c;
                   }
                   /* decoding loop */
                   c = 0;
                   c =| *p1++;
                   if (c==' ' || c=='\n') {
                           b1 = token;
                           b2 = token >> 8;
                           if (lastc!=' ' && lastc!='\n') {
                                   /* end of token */
                                   if (sp>0) {
                                           if (nfirst) putc(lastb2, obuf);
                                           putc(b1, obuf);
                                           lastb2 = b2;
                                           nfirst = 1;
                                   } else {
                                           /* first token in the line */
                                           bytecnt = token;
                                   }
                           }
                           if (c==' ') sp++;
                           else {
                                   /* new line */
                                   sp = 0;
                                   fflush(obuf);
                           }
                           token = 0;
                   } else {
                           /* actual hex and octal conversion */
                           token =* sp>0 ? 16 : 8;
                           token =+ c<='9' ? c-'0' : c-'W';
                   }
                   lastc = c;
           }
           if (!(bytecnt & 1)) {
                   putc(lastb2, obuf);
                   fflush(obuf);
           }
           close(ibuf[0]);
           close(obuf[0]);
   } else if (argc>1) {
           diag(argv[1]);
           diag(": cannot open\n");
   } else {
           diag("error: filename missing\n");
   }
}

diag(s)
char *s;
{
   while(*s)
           write(2,s++,1);
}

UPD。我在GitHub 上發布了一個更快、更簡單的版本,其中還突出顯示了語法。

引用自:https://unix.stackexchange.com/questions/528208