Печать uint8_t в Arduino
Я изучаю esp8266, используя Arduino IDE. Я все еще новичок в программировании плат разработки. Я пытался использовать криптобиблиотеку. Я пробую AES в Arduino и выбрал эту библиотеку, потому что она казалась полной и была одной из немногих библиотек, использующих ECB. Моя проблема в том, что при вызове функции шифрования я путаюсь с выводом.
Это то, что я сделал на данный момент.
#include <Crypto.h>
#include <AES.h>
#include <string.h>
AESSmall128 aes128;
void setup()
{
Serial.begin(9600);
uint8_t key = (uint8_t)1234567654321234;
aes128.setKey(&key, 16);
uint8_t output = 0;
Serial.println("before");
Serial.print(output);
uint8_t input = (uint8_t)9164567654321234;
aes128.encryptBlock(&output, &input);
Serial.println("after");
Serial.print(output);
}
void loop()
{
}
Когда я печатаю вывод
, он возвращает 252
. Что такое 252? Почему только 252? Это кажется очень коротким, глядя на это. Почему он не выводит строки?
@Adis, 👍1
Обсуждение2 ответа
Лучший ответ:
uint8_t
— это 8-битное целое число без знака, поэтому диапазон значений, которые он может представлять, составляет от 0 до 255.
Когда вы приводите длинные/большие значения к uint8_t
, вы, по сути, показываете только наименее значимые 8 бит.
Однако функции decryptBlock()
и encryptBlock()
ожидают массив байтов , а не один байт.
Библиотека, на которую вы ссылаетесь, отмечает прямо в связанной позиции, что длина выходных и входных параметров должна быть не менее blockSize()
байт. Ссылаясь на blockSize()
, он отмечает, что эта функция всегда возвращает 16
. Поэтому вам нужно передать массив из uint8_t
длиной не менее 16.
Когда вы определяете переменные для ключа, открытого текста и зашифрованного текста, вам нужно определить их не как однобайтовый тип, а как массив байтов:
uint8_t[16] key = {1,2,3,4,5,6,7,6,5,4,3,2,1,2,3,4}; // Кстати, это не очень хороший ключ
uint8_t[16] output = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t[16] input = {9,1,6,4,5,6,7,6,5,4,3,2,1,2,3,4};
(При передаче массива вам не нужно разыменовывать переменную, поэтому вызовите aes128.setKey(key, 16);
и т. д. Опустите &
)
Каждый из 16 байтов может иметь значение в диапазоне от 0 до 255. Они не обязательно должны быть ограничены однозначными числами; Я просто скопировал/перевел то, что вы написали, чтобы продемонстрировать пример. Вы можете установить свой ключ следующим образом:
uint8_t[16] key = {66,127,164,72,68,158,148,255,23,36,226,192,198,248,251,221};
Вы также можете ссылаться на байты в двухзначном шестнадцатеричном представлении:
uint8_t[16] key = {0xa6,0x09,0x81,0xc5,0xb8,0xf6,0x9a,0x33,0x75,0x24,0xff,0x79,0xd3,0x48,0x4f,0x1d);
ОБНОВЛЕНИЕ для адресных строк
Строка в стиле C представляет собой последовательность байтов с типом char
для обозначения данных ASCII, хотя теоретически может работать любой байтовый тип. Последовательность байтов заканчивается значением 0
(т. е. 0x00
, а не символом ASCII '0'
), поэтому вы должны помнить, что байт завершения занимает байт памяти.
Чтобы инициализировать ключ строкой:
const unsigned char[17] key = "helloareyouarehi"; // 16 символов и завершение в 1 байт означает, что в памяти зарезервировано всего 17 байт.
Я не исследовал, как используемая вами криптобиблиотека обрабатывает строки в стиле C, поэтому предположим, что она вообще их не распознает, и нам придется самим завершать наши строки нулем.
char[17] output = {0}; // Инициализируемся всеми нулями
char[17] input = "iwanttoencryptme";
aes128.encryptBlock(output, input);
output[16] = 0x00; // На всякий случай поместите нулевой терминатор в последний слот.
Serial.print(output);
Если функция encryptBlock()
меняет только 16 байт в выходном массиве, то от инициализации может остаться 17-й (нулевой), но не зная, сохраняет ли функция строки, лучше будь в безопасности, чем потом сожалей.
Привет @jose, большое спасибо за ответ. Прежде чем продолжить, да, я знаю, что это не очень хороший ключ, я просто опробую библиотеку ради развлечения. Теперь я стал лучше понимать после того, как вы объяснили, что они представляют значения от 0 до 255. Теперь мой вопрос: представляют ли эти числа значения ASCII?, @Adis
Значения ASCII представляют собой байты, но обычно они находятся в диапазоне от 0 до 128 и даже меньше для печатного ASCII. Если вы хотите начать работать со строками, а не с массивами чисел, вам следует проявлять особую осторожность при чтении и записи строковых данных., @jose can u c
Хорошо, допустим, я хотел, чтобы мой ключ был «привет, вы, привет», как это будет представлено в виде массива uint8_t
? А вывести массив uint8_t?, @Adis
Ах да, разве это не должно быть uint8_t key [] = {1,2,3,4,5,6,7,6,5,4,3,2,1,2,3,4};
С точки зрения синтаксиса?, @Adis
Инициализация массива может иметь явное или неявное определение размера. Я предпочитаю явно определять размер массива., @jose can u c
Хорошо, Хосе, сейчас тестирую. Я расскажу вам через несколько минут, как это происходит., @Adis
Я получаю сообщение об ошибке:
ошибка: недопустимое преобразование из 'char*' в 'const uint8_t* {aka const unsigned char*}' [-fpermissive]
, @Adis
Какое утверждение вызывает эту ошибку?, @jose can u c
в функции шифрования, хотя я привел его к (uint8_t*)
, но теперь мой вывод — нечитаемые символы 0⸮⸮⸮⸮X⸮,O⸮e⸮
., @Adis
У меня недостаточно представителей, не могли бы вы перенести это в чат? или может быть я могу связаться с вами лично?, @Adis
Давайте [продолжим обсуждение в чате](https://chat.stackexchange.com/rooms/87044/discussion-between-jose-can-uc-and-adis)., @jose can u c
Ширина uint8_t
составляет ровно 8 бит, поэтому он может содержать значения от 0 до 255. Однако ширина вашего числа составляет около 54 бит.
Я думаю, вам следует использовать массив.
Кроме того, числовые литералы обычно имеют тип int, поэтому даже если у вас достаточно места для них, они получают неправильное значение. Необходимо использовать что-то вроде uint64_t value = UINT64_C(1234567654321234);
- AT-команда не отвечает на последовательный монитор
- Отправка данных Arduino в MySQL с помощью phpMyAdmin и XAMPP на Windows10
- Arduino выводит значения мусора на serial monitor с ESP8266
- ошибка: espcomm_upload_mem failed при загрузке скетча
- фатальная ошибка ESP8266WiFi.h: Такого файла или каталога нет
- Как подключить Wi-Fi Shield ESP-12E-ESP8266-UART-WIFI-Wireless-Shield к Arduino
- Получить данные с сайта с помощью ESP8266 с помощью AT-команд
- Захват изображений с OV7670 (без FIFO) с использованием Arduino Uno?
Вы видели пример? https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/examples/TestAESSmall/TestAESSmall.ino, @Jot
Привет. Я пробовал примеры. Они не выводят никаких результатов шифрования/дешифрования. Тестовые примеры предназначены для «проверки производительности». Я закончил этот вопрос, посмотрите ответ Хосе. Спасибо., @Adis