у меня есть char a[]
шестнадцатеричных символов, таких как это:
«315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e»
Я хочу преобразовать его в буквы, соответствующие каждому шестнадцатеричному числу, например:
68656c6c6f = hello
и сохранить его в char b[]
а затем сделать обратное
Мне не нужен блок кода, пожалуйста, я хочу объяснения, какие библиотеки использовались и как их использовать.
Спасибо
Вот простой кусок кода, чтобы сделать трюк:
unsigned int hex_digit_value(char c)
{
if ('0' <= c && c <= '9') { return c - '0'; }
if ('a' <= c && c <= 'f') { return c + 10 - 'a'; }
if ('A' <= c && c <= 'F') { return c + 10 - 'A'; }
return -1;
}
std::string dehexify(std::string const & s)
{
std::string result(s.size() / 2);
for (std::size_t i = 0; i != s.size(); ++i)
{
result[i] = hex_digit_value(s[2 * i]) * 16
+ hex_digit_value(s[2 * i + 1]);
}
return result;
}
Использование:
char const a[] = "12AB";
std::string s = dehexify(a);
Заметки:
Правильная реализация добавит проверки, что длина входной строки является четной и что каждая цифра на самом деле является действительным шестнадцатеричным числом.
Dehexifying не имеет ничего общего с ASCII. Это просто получается любой шестнадцатеричная последовательность кусков в последовательность байтов. Я просто использую std::string
как удобный «контейнер байтов», который является именно тем, чем он является.
На SO есть десятки ответов, показывающих, как идти другим путем; просто искать «hexify».
Предполагая, что вы говорите о кодах ASCII. Ну, первый шаг — найти размер b
, Предполагая, что у вас есть все символы с 2 шестнадцатеричными цифрами (например, табуляция было бы 09
), то размер b
это просто strlen(a) / 2 + 1
,
Что сделано, вам нужно пройти через письма a
, 2 на 2, преобразуйте их в целочисленные значения и сохраните в виде строки. Написано как формула у вас есть:
b[i] = (to_digit(a[2*i]) << 4) + to_digit(a[2*i+1]))
где to_digit(x)
новообращенные '0'-'9'
в 0-9
а также 'a'-'z'
или же 'A'-'Z'
в 10-15
,
Обратите внимание, что если символы ниже 0x10
показаны только с одним символом (единственный, о котором я могу думать, табуляция, тогда вместо использования 2*i
как указатель на a
, вы должны держать next_index
в вашем цикле, который либо добавляется 2, если a[next_index] < '8'
или добавлено 1 в противном случае. В последнем случае b[i] = to_digit(a[next_index])
,
Реверс этой операции очень похож. Каждый персонаж b[i]
записывается как:
a[2*i] = to_char(b[i] >> 4)
a[2*i+1] = to_char(b[i] & 0xf)
где to_char
противоположность to_digit
,
Преобразование шестнадцатеричной строки в строку символов можно выполнить с помощью std::substr
чтобы получить следующие два символа шестнадцатеричной строки, затем с помощью std::stoi
преобразовать подстроку в целое число. Это может быть приведено к персонажу, который добавляется к std::string
, std::stoi
функция только C ++ 11, и если у вас ее нет, вы можете использовать, например, std::strtol
.
Чтобы сделать обратное, вы зацикливаетесь на каждом символе во входной строке, приводите его к целому числу и помещаете его в std::ostringstream
предшествуют манипуляторы, чтобы представить его как двузначный, нулевая приставка шестнадцатеричное число. Добавить к выходной строке.
использование std::string::c_str
чтобы получить старый стиль C char
указатель при необходимости.
Нет внешней библиотеки, только с использованием стандартной библиотеки C ++.
Вперед:
Задний ход:
Почти забыл упомянуть. stdio.h и обычное время выполнения C требуется только при условии, что вы используете sscanf
а также sprintf
, В качестве альтернативы вы могли бы создать пару таблиц конверсии, которые радикально ускорили бы конверсии.
Каждая шестнадцатеричная цифра соответствует 4 битам, потому что 4 бита имеют 16 возможных битовых комбинаций (и есть 16 возможных шестнадцатеричных цифр, каждая из которых обозначает уникальный 4-битный шаблон).
Итак, две шестнадцатеричные цифры соответствуют 8 битам.
И на большинстве компьютеров в настоящее время (некоторые цифровые сигнальные процессоры Texas Instruments являются исключением) C ++ char
8 бит.
Это означает, что каждый C ++ char
представлен 2 шестнадцатеричными цифрами.
Итак, просто прочитайте две шестнадцатеричные цифры за раз, преобразовать в int
используя, например, istringstream
, преобразовать это в char
и добавить каждый char
значение для std::string
,
Другое направление прямо противоположное, но с изюминкой.
Так как char
подписан на большинстве систем, вам нужно преобразовать в unsigned char
перед преобразованием этого значения снова в шестнадцатеричные цифры.
Преобразование в и из шестнадцатеричного можно сделать с помощью hex
как, например,
cout << hex << x;
cin >> hex >> x;
для подходящего определения x
например, int x
Это должно работать и для строковых потоков.