Инициализация массива без знака с шестнадцатеричными значениями в C++
Я хотел бы инициализировать массив без знака с 16 шестнадцатеричными значениями. Тем не менее, я не знаю, как правильно инициализировать / получить доступ к этим значениям. Когда я пытаюсь получить к ним доступ, как хотелось бы, интуитивно, я не получаю никакой ценности вообще.
Это мой вывод
The program was run with the following command: 4
Please be a value! -----> p
Here's some plaintext
при запуске с кодом ниже -
int main(int argc, char** argv)
{
int n;
if (argc > 1) {
n = std::stof(argv[1]);
} else {
std::cerr << "Not enough arguments\n";
return 1;
}
char buff[100];
sprintf(buff,"The program was run with the following command: %d",n);
std::cout << buff << std::endl;
unsigned char plaintext[16] =
{0x0f, 0xb0, 0xc0, 0x0f,
0xa0, 0xa0, 0xa0, 0xa0,
0x00, 0x00, 0xa0, 0xa0,
0x00, 0x00, 0x00, 0x00};
unsigned char test = plaintext[1]^plaintext[2];
std::cout << "Please be a value! -----> " << test << std::endl;
std::cout << "Here's some plaintext " << plaintext[3] << std::endl;
return 0;
}
В контексте, это часть группового проекта для школы. В конечном итоге мы пытаемся внедрить шифр Serpent, но продолжаем сталкиваться с неподписанными массивами символов. В спецификации нашего проекта говорится, что у нас должно быть две функции, которые принимают байтовые массивы в Java. Я предполагаю, что ближайший родственник в C++ - это unsigned char[]. В противном случае я бы использовал вектор. В другом месте в коде я реализовал функцию setKey, которая принимает массив unsigned char, упаковывает его значения в 4 длинных целых числа (ключ должен быть 256 бит) и выполняет различные операции по сдвигу битов и xor для этих целых чисел для генерации ключи, необходимые для криптографического алгоритма. Надеюсь, этого достаточно, чтобы понять, что я собираюсь сделать. Я предполагаю, что я просто пропускаю некоторые основные функции C++ здесь. Спасибо за любую помощь!
3 ответа
char
является 8-битным значением, способным хранить -128 <= n <= +127, часто используемым для хранения символьных представлений в различных кодировках и обычно - в западных установках с латинским алфавитом - char
используется для указания представления кодированных значений ASCII или utf. "Кодированный" означает, что символам / букве в наборе символов были присвоены числовые значения. Подумайте о периодической таблице как о кодировке элементов, так что 'H' (водород) кодируется как 1, германий - как 32. В таблицах ASCII (и UTF-8) позиция 32 представляет символ, который мы называем "пробел".
Когда вы используете operator <<
для значения char поведение по умолчанию предполагает, что вы передаете ему кодировку символов, например код символа ASCII. Если вы делаете
char c = 'z';
char d = 122;
char e = 0x7A;
char f = '\x7a';
std::cout << c << d << e << f << "\n";
Все четыре задания эквивалентны. "z" является ярлыком / синтаксическим сахаром для char(122)
, 0x7A
является шестнадцатеричным для 122, а '\x7a' является escape, который формирует символ ascii со значением 0x7a или 122 - iez
Многие начинающие программисты ошибаются в том, что они делают это:
char n = 8;
std::cout << n << endl;
это не печатает "8", это печатает символ ASCII в позиции 8 в таблице ASCII.
Задумайтесь на минуту:
char n = 8; // stores the value 8
char n = a; // what does this store?
char n = '8'; // why is this different than the first line?
Давайте перемотать момент: когда вы храните 120
в переменной он может представлять символ ASCII 'x'
, но в конечном итоге то, что хранится, это просто числовое значение 120
, легко и просто.
В частности: когда вы проходите 122
функции, которая в конечном итоге будет использовать ее для поиска записи шрифта из набора символов с использованием кодировок Latin1, ISO-8859-1, UTF-8 или аналогичных, а затем 120
средства 'z'
,
В конце дня, char
это просто один из стандартных типов целочисленных значений, он может хранить значения -128 <= n <= +127
, это может быть тривиально short
, int
, long
или же long long
и т. д. и т. д.
Хотя он обычно используется для обозначения символов, он также часто используется как способ сказать "я храню только очень маленькие значения" (например, целочисленные проценты).
int incoming = 5000;
int outgoing = 4000;
char percent = char(outgoing * 100 / incoming);
Если вы хотите напечатать числовое значение, вам просто нужно перевести его в другой тип значения:
std::cout << (unsigned int)test << "\n";
std::cout << unsigned int(test) << "\n";
или предпочтительный способ C++
std::cout << static_cast<unsigned int>(test) << "\n";
Я думаю (не совсем понятно, что вы спрашиваете), что ответ так прост, как этот
std::cout << "Please be a value! -----> " << static_cast<unsigned>(test) << std::endl;
Если вы хотите вывести числовое значение char или unsigned char, вы должны сначала привести его к типу int или unsigned.
Неудивительно, что по умолчанию символы выводятся в виде символов, а не целых чисел.
Кстати этот прикольный код
char buff[100];
sprintf(buff,"The program was run with the following command: %d",n);
std::cout << buff << std::endl;
проще записать как
std::cout << "The program was run with the following command: " << n << std::endl;
std::cout
а также std::cin
всегда рассматривает переменную char как char
Если вы хотите ввести или вывести как int, вы должны сделать это вручную, как показано ниже.
std::cin >> int_var; c = int_var;
std::cout << (int)c;
При использовании scanf или printf такой проблемы нет, так как параметр формата ("%d", "%c", "%s") указывает, как скрыть входной буфер (целое число, символ, строка).