Я уверен, что для (некоторых) языков сценариев, которые могут быть достигнуты, и хотелось бы посмотреть, как это сделать. Можем ли мы доказать, что комментарий верно для C тоже?
NB: это не означает, что hex - это двоичный код ASCII - в частности, выход должен быть необработанным октетом, соответствующим входному шестнадцатеричному ASCII. Кроме того, входной парсер должен пропускать/игнорировать пробелы.
Ответ 7
Г.
Вам не позволено называть меня моими оценками!;-P
Здесь версия с 9 строками C без нечетного форматирования (ну, я дам вам, что массив tohex лучше разбит на 16 строк, чтобы вы могли видеть, какие кодовые символы сопоставляются с какими значениями...) и только 2 ярлыков, которые я бы не разворачивал ничем, кроме одноразового script:
#include <stdio.h>
char hextonum[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
char input[81]="8b1f0008023149f60300f1f375f40c72f77508507676720c560d75f002e5ce000861130200000000";
void main(void){
int i = 0;
FILE *fd = fopen("outfile.bin", "wb");
while((input[i] != 0) && (input[i+1] != 0))
fputc(hextonum[input[i++]] * 16 + hextonum[input[i++]], fd);
}
Нет комбинированных строк (каждому выражению присваивается собственная строка), он отлично читается и т.д. Запущенная версия, несомненно, может быть короче, можно обмануть и поместить тесные фигурные скобки в ту же строку, что и предыдущий, и т.д. и т.д., и т.д.
Две вещи, которые мне не нравятся, это то, что у меня нет близкого (fd) там, и main не должен быть недействительным и должен возвращать int. Возможно, они не нужны - ОС выпустит каждый ресурс, который использует программа, файл будет закрыт без каких-либо проблем, и компилятор позаботится о выходе из программы. Учитывая, что это одноразовое использование script, оно приемлемо, но не развертывайте это.
Он становится одиннадцатью строками с обоими, поэтому он не является огромным увеличением в любом случае, и десятистрочная версия будет включать в себя тот или иной, в зависимости от того, что может показаться лизингодателем двух зол.
Он не выполняет никаких проверок ошибок и не допускает пробелов - если предположить, что это одноразовая программа, то быстрее выполнять поиск/замену и избавляться от пробелов и пробелов перед запуском script, однако не нужно больше, чем еще несколько строк, чтобы есть пробелы.
Есть, конечно, способы сделать его короче, но они, вероятно, значительно уменьшат читаемость...
Хммм. Просто прочитайте комментарий о длине строки, так что здесь более новая версия с более уродливым макросом hextonum, а не массив:
#include <stdio.h>
#define hextonum(x) (((x)<'A')?((x)-'0'):(((x)<'a')?((x)+10-'A'):((x)+10-'a')))
char input[81]="8b1f0008023149f60300f1f375f40c72f77508507676720c560d75f002e5ce000861130200000000";
void main(void){
int i = 0;
FILE *fd = fopen("outfile.bin", "wb");
for(i=0;(input[i] != 0) && (input[i+1] != 0);i+=2)
fputc(hextonum(input[i]) * 16 + hextonum(input[i+1]), fd);
}
Это не ужасно нечитаемо, но я знаю, что у многих людей есть проблемы с тройным оператором, но соответствующее присвоение имени макроса и некоторый анализ должны с готовностью давать, как это работает для среднего программиста на C. Из-за побочных эффектов в макросе мне пришлось переходить в цикл for, поэтому мне не нужно было иметь другую строку для я + = 2 (hextonum(i++)
будет увеличивать я на 5 каждый раз, когда она вызывается, макро-побочные эффекты не для слабый от сердца!).
Кроме того, анализатор ввода должен пропускать/игнорировать пробелы.
роптать, ворчать, ворчать.
Мне пришлось добавить несколько строк, чтобы позаботиться об этом требовании, теперь до 14 строк для достаточно форматированной версии. Он будет игнорировать все, что не является шестнадцатеричным символом:
#include <stdio.h>
int hextonum[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
char input[]="8b1f 0008 0231 49f6 0300 f1f3 75f4 0c72 f775 0850 7676 720c 560d 75f0 02e5 ce00 0861 1302 0000 0000";
void main(void){
unsigned char i = 0, nibble = 1, byte = 0;
FILE *fd = fopen("outfile.bin", "wb");
for(i=0;input[i] != 0;i++){
if(hextonum[input[i]] == -1)
continue;
byte = (byte << 4) + hextonum[input[i]];
if((nibble ^= 0x01) == 0x01)
fputc(byte, fd);
}
}
Я не беспокоился с длиной строки 80 символов, потому что входной сигнал не менее 80 символов, но трехмерный трехмерный макрос может заменить первый 256-элементный массив. Если кто-то не возражал против "альтернативного форматирования", то следующая 10-строчная версия не полностью нечитаема:
#include <stdio.h>
int hextonum[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
char input[]="8b1f 0008 0231 49f6 0300 f1f3 75f4 0c72 f775 0850 7676 720c 560d 75f0 02e5 ce00 0861 1302 0000 0000";
void main(void){
unsigned char i = 0, nibble = 1, byte = 0;
FILE *fd = fopen("outfile.bin", "wb");
for(i=0;input[i] != 0;i++){
if(hextonum[input[i]] == -1) continue;
byte = (byte << 4) + hextonum[input[i]];
if((nibble ^= 0x01) == 0x01) fputc(byte, fd);}}
И, опять же, дальнейшая обфускация и свертывание бит могут привести к еще более короткому примеру.