Печать 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? Это кажется очень коротким, глядя на это. Почему он не выводит строки?

, 👍1

Обсуждение

Вы видели пример? https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/examples/TestAESSmall/TestAESSmall.ino, @Jot

Привет. Я пробовал примеры. Они не выводят никаких результатов шифрования/дешифрования. Тестовые примеры предназначены для «проверки производительности». Я закончил этот вопрос, посмотрите ответ Хосе. Спасибо., @Adis


2 ответа


Лучший ответ:

4

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


1

Ширина uint8_t составляет ровно 8 бит, поэтому он может содержать значения от 0 до 255. Однако ширина вашего числа составляет около 54 бит.

Я думаю, вам следует использовать массив.

Кроме того, числовые литералы обычно имеют тип int, поэтому даже если у вас достаточно места для них, они получают неправильное значение. Необходимо использовать что-то вроде uint64_t value = UINT64_C(1234567654321234);

,