Преобразовать шестнадцатеричное в двоичное в C - PullRequest
0 голосов
/ 19 октября 2018

В настоящее время я поддерживаю код, который я унаследовал от предыдущего разработчика.Я должен понять одну функцию, которая конвертирует идентификатор из Hex в Binay.Я не могу полностью понять его логику за этим.Ниже приведен код,

int iHex2Bin(char * pchIn, char * pchOut, int iLen)
{
int i;

memset(pchOut, 0, iLen);

for(i=0; i<iLen; i++)
{
    pchOut[i] = (((unsigned char) *pchIn)-0x30)*16;
    pchIn++;
    pchOut[i] += (((unsigned char) *pchIn)-0x30);

    pchIn++;
}
return(0);
}

Как следует из названия, он преобразует шестнадцатеричное в бин.Я не понимаю логику функции.Кто-нибудь может это объяснить?Спасибо.

Спасибо за ваши ответы.Это немного ясно сейчас.Я также добавляю противоположную функцию для дополнительной классификации:

int iBin2Hex (char * pchIn, char * pchOut, int iLen) {int i;

unsigned char chInBuff[256]={0};
char chOutBuff[513]={0};
char chTemp[3]={0};

if(iLen>256)
    return(-2);

memcpy(chInBuff, pchIn, iLen);
for(i=0; i<iLen; i++)
{
    sprintf(chTemp, "%02X", chInBuff[i]);
    strcat(chOutBuff, chTemp);
}

memcpy(pchOut, chOutBuff, iLen*2 + 1);
return(SUCCESS);

}

Я думаю, что эти функции необходимы, и название функции очень запутанно.Функция библиотеки C может быть использована.Но код просыпается правильно, и поэтому я не сделал никаких изменений.Мне просто нужно понять код, если это понадобится в будущем.

Ответы [ 3 ]

0 голосов
/ 19 октября 2018

Если код внутри функции правильный, то функция названа неправильно.Это выглядит любительским, но вполне возможно, что оно предназначено для чтения последовательности цифр ASCII (независимо от того, каков набор символов выполнения реализации C) и записи десятичного двоичного кода .

Например, эта процедура может служить для чтения текста в ASCII и подготовки его для использования в финансовом программном обеспечении, которое использует двоично-десятичный код.(Системы, в которых не используется ASCII, в наши дни встречаются редко, а системы или приложения, использующие двоично-десятичную дробь, встречаются редко, но тот факт, что в коде присутствуют признаки того и другого, является некоторым свидетельством намерения, а не аварии.)

Имея это в виду, мы можем интерпретировать код:

for(i=0; i<iLen; i++)

Это повторяется один раз для каждой пары выходных цифр.Таким образом, количество обработанных цифр равно 2*iLen, а количество записанных байтов равно iLen.

    pchOut[i] = (((unsigned char) *pchIn)-0x30)*16;

Это берет один символ из ввода и вычитает код ASCII для «0».Поскольку цифры ASCII от «0» до «9» имеют последовательные коды, результатом является число, представленное цифрой от 0 до 9. Затем это число умножается на 16, фактически на левое смещение, и сохраняется в текущем выходном байте.

    pchOut[i] += (((unsigned char) *pchIn)-0x30);

Это вычисляет число, представленное следующим входным символом, и добавляет его к текущему выходному байту.В результате две цифры упакованы в один байт, каждый из которых закодирован в четыре бита.Например, десятичная цифра «74» на входе будет закодирована как 74 16 (0x74), что составляет 116 10 .

0 голосов
/ 19 октября 2018

В дополнение к тому, что другие говорят как неправильные, код может использовать приведенное ниже для преобразования последовательных пар шестнадцатеричных символов в байт

// inside the loop
pchOut[i] = strtoul((char[3]){pchIn[0], pchIn[1]}, 0,16);
pchIn += 2;

При этом используется литеральный символ, доступный с C99.

0 голосов
/ 19 октября 2018

Я не думаю, что функция делает именно то, что вам сказали.Он принимает строку символов в качестве входных данных и создает другую строку символов в качестве выходных данных, но я бы неохотно обозначил ввод как «шестнадцатеричный».Вывод представляет собой последовательность байтов со знаком, содержащих двоичные значения.

Давайте рассмотрим суть кода: выражение (((unsigned char) *pchIn)-0x30).Это читает один символ и вычитает 0x30, что является значением ASCII для '0'.Таким образом, это выражение правильно преобразует ASCII-цифру в значение от 0 до 9. Оно неправильно обрабатывает любые другие символы.В частности, он не выдаст правильные значения 10-15 для символов от 'A' до 'F' или 'a' до 'f'.Тот факт, что альтернативные символы во входной строке умножаются на 16 ... нет, этого недостаточно, чтобы сделать этот шестнадцатеричный код.

По сути, он принимает (предположительно четную длину) строку байтов A, B, C, D, ... и преобразование его в строку байтов A * 16 + B, C * 16 + D, ...

Вам гораздо лучше использовать одну из стандартных функций библиотекипреобразовать строку в фактическое двоичное значение (скажем, int), которое очень легко проверить, распечатать и т. д., а затем преобразовать это двоичное значение в другую строку в другом формате.Обратитесь к любому руководству или онлайн-документации.Я верю, что strtol и ltoa сделают то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...