Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.98/120: Рейтинг темы: голосов - 120, средняя оценка - 4.98
3 / 3 / 0
Регистрация: 02.01.2016
Сообщений: 160

Ввод/вывод звука по I2S, используя ESP32

03.06.2021, 19:53. Показов 29912. Ответов 40

Студворк — интернет-сервис помощи студентам
Добрый день друзья!
Подскажите пожалуйста ответ на такую задачу.
Есть необходимость сделать следующее. Перечислю устройства последовательно, по мере прохождения звукового сигнала.
1. Всенаправленный MEMS-микрофон интерфейса I2S - INMP441 INMP441.
2. ESP32.
3. Плата DAC декодера интерфейса I2S - PCM5102A.

Далее. Звук с микрофона по шине I2S заворачиваем на ESP32 (благо есть такой интерфейс), обрабатываем как нам необходимо и также по шине I2S передаем на ЦАП PCM5102A.

Под обработкой, как нам необходимо, в идеале, следует понимать применение шифрования. Т.е. ESP32 предполагается использовать для шифрования и соответственно расшифровки. Но для начала шифрование вообще не будем затрагивать.

На данном этапе задача - это с микрофона ввести звук по шине I2S в ESP32 и вывести этот же звук по I2S на ЦАП.

Сразу честно скажу, что прям такого большого опыта с обработкой звука у меня нет. Были различные другие проекты с датчиками температуры, модулями Lora и т.д. Со звуком не работал и также с шиной I2S.

В интернете много различной информации, но вот как сделать одновременно - вводить и тут же выводить звук на/с ESP32 я не нашел... Если возможно, подскажите пожалуйста или направьте! Буду очень признателен. Если у кого был также опыт с шифрованием звука, то подскажите если можно (посоветуйте какую библиотеку или подобные проекты...).
СПАСИБО!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.06.2021, 19:53
Ответы с готовыми решениями:

esp32 и i2s аудио
Всё подключил, работает. Но как только подношу палец близко - начинаются помехи (на видео они слышны). Причём, когда касаюсь контактов (в...

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

Ввод-вывод звука черезмикрофон/динамики - кто делал?
Дано: Windows(2000Prof), VS.NET 2003. Можно и обычный C++ от 5-ой студии ))) Народ - есть вопрос - кто-нибудь вводил звук через...

40
3 / 3 / 0
Регистрация: 02.01.2016
Сообщений: 160
23.06.2021, 13:48  [ТС]
Студворк — интернет-сервис помощи студентам
Добрый день!
Объясните пожалуйста по простому и как можно подробней следующее.
Почему, если я вставляю что-либо, что требует время на обработку, между функцией i2s_read_bytes и функцией i2s_write_bytes, то на выходе шипение и бульканье?

Как я рассуждаю:
1. Считали buf (определенное количество сэмплов) с микрофона.
2. Ждем (некоторое время, в мс). Эта пауза нужна для обработки сэмплов.
3. Записываем обработанный buf на ЦАП.
4. Цикл повторяется.

Да, получается что после того, как мы считали с микрофона, далее мы ничего не считываем, а обрабатываем и потом отправляем buf на ЦАП. Только после этого мы опять считываем с микрофона. Т.е. для шины I2S микрофона есть пауза между концом считывания и началом считывания.
Тоже самое и для шины I2S для ЦАПа.

Как решить это? Посоветуйте! Мне важно понять как это работает и почему из-за небольшой паузы между i2s_read_bytes и функцией i2s_write_bytes возникает ерунда...
0
Эксперт по электронике
6998 / 3314 / 341
Регистрация: 28.10.2011
Сообщений: 13,024
Записей в блоге: 7
24.06.2021, 22:45
Цитата Сообщение от mike84 Посмотреть сообщение
Почему, если я вставляю что-либо, что требует время на обработку, между функцией i2s_read_bytes и функцией i2s_write_bytes, то на выходе шипение и бульканье?
Потому что выводить данные нужно непрерывно. Если прерывать, то что будет воспроизводится? Правильно - ничего! А раз ничего, возникают паузы в воспроизведении которые слышны как вы описали.

Цитата Сообщение от mike84 Посмотреть сообщение
Как я рассуждаю:
1. Считали buf (определенное количество сэмплов) с микрофона.
2. Ждем (некоторое время, в мс). Эта пауза нужна для обработки сэмплов.
3. Записываем обработанный buf на ЦАП.
4. Цикл повторяется.
Нужно как минимум три буфера. Один считывается, другой обрабатывается, третий воспроизводится. Работа с ними должна быть одновременной и без задержек при вводе / выводе звука. Бдуту задержки - будет потеря данных и искажение звука.

Цитата Сообщение от mike84 Посмотреть сообщение
Да, получается что после того, как мы считали с микрофона, далее мы ничего не считываем
Читать нужно непрерывно и отправлять в ЦАП тоже.

Цитата Сообщение от mike84 Посмотреть сообщение
Т.е. для шины I2S микрофона есть пауза между концом считывания и началом считывания.
Тогда не удивляйтесь что звук искажается.
1
3 / 3 / 0
Регистрация: 02.01.2016
Сообщений: 160
24.06.2021, 23:34  [ТС]
locm, большое спасибо за подробное объяснение!!!

Принцип я понял. Начал прикидывать как это реализовать и возник такой вопрос.
Исходя из Вашего объяснения нужно делать вот так:

Примем, что buf_1 - это буфер считывания, buf_2 - буфер обработки, buf_3 - буфер отправки.
Тогда работа должна идти следующим образом. В каждый такт мы должны одновременно выполнять все три операции: считывание, обработку и отправку. Но для того, чтобы начать первый такт, нам нужны пустые (случайные) buf_2 и buf_3, чтобы было что обрабатывать и отправлять. На втором такте уже все будет.



Но как это организовать одновременно? Что я имею ввиду?...
Опишу, например, такт 2:
loop{
1. Считываем, получаем buf_1.
2. Обрабатываем buf_1 (предыдущего такта), получаем buf_2.
3. Отправляем buf_3 - (обработанный buf_2 предыдущего такта).
}

В loop все равно происходит последовательная работа 1 --> 2 --> 3. И между функциями i2s_read_bytes (операция 1) и i2s_write_bytes (операция 3) есть операция 2, которая тоже занимает какое-то время. Получается, что считывание из I2S и отправка в I2S как таково не будет происходить одно за другим.
Т.е. (для проверки этого) операцию 2 можно заменить delay(x), и то, что прочитали, потом отправлять (как я сделал в последнем своем коде).

Или я в чем-то не прав? Пожалуйста поправьте.
0
3 / 3 / 0
Регистрация: 02.01.2016
Сообщений: 160
25.06.2021, 08:29  [ТС]
Возможно нужно к тому что сказано выше применить функции i2s_start() и i2s_stop() ?

Как сделать, чтобы именно в один и тот же момент времени происходило считывание, обработка и отправка?
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
25.06.2021, 08:39
Цитата Сообщение от mike84 Посмотреть сообщение
Как сделать, чтобы именно в один и тот же момент времени происходило считывание, обработка и отправка?
использовать кольцевой буфер
0
3 / 3 / 0
Регистрация: 02.01.2016
Сообщений: 160
25.06.2021, 10:39  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
использовать кольцевой буфер
То, что это называется кольцевым буфером я знаю. Как видите, я пытаюсь разобраться как он работает и как его сделать.

locm, если возможно, ответьте пожалуйста на мои последние сообщения.
0
Эксперт по электронике
6998 / 3314 / 341
Регистрация: 28.10.2011
Сообщений: 13,024
Записей в блоге: 7
25.06.2021, 11:54
Цитата Сообщение от mike84 Посмотреть сообщение
В каждый такт мы должны одновременно выполнять все три операции
Из I2S нужно считывать данные как только были приняты с минимальной задержкой. Нужно отправлять в I2S как только были отправлены предыдущие, с минимальной задержкой. Не должно быть ситуации что данные получены, но не считаны, или отправлены, но не загружены новые. Обычно это производится в прерывании по приему / передаче. Если есть возможность сделать через DMA это упростит задачу. Затрачиваемое время на обработку должно быть меньше чем нужно для приема / передачи одного пакета.
0
3 / 3 / 0
Регистрация: 02.01.2016
Сообщений: 160
29.06.2021, 09:55  [ТС]
Привет Друзья!
Сразу говорю, что в отношении аудиоконвейера ничего не сделал. Я работаю в Arduino IDE, и под неё не нашел подходящих библиотек. Зато нашел другую библиотеку шифрования, при помощи которой можно шифровать примерно в сотни раз быстрей и думаю все должно получиться.
Если прошлая библиотека шифровала 16 значений примерно за 3,5 мс, то эта библиотека за 50 мкс. Это я проверял лично.
Вот код со сравнением:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "aes256.h"
int a;
//    Библиотека "aes256.h"   начало кода
aes256_context ctxt;                          // команда библиотеки "aes256.h"     
uint8_t Data[] = { // Данные - 16 символа     // команда библиотеки "aes256.h"                    
                 0x01, 0x03, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x03, 0x01, 0x05, 0x03, 0x07, 0x05, 0x06, 0x02};  
uint8_t key[] = { // Ключ шифрования - 32 символа     // команда библиотеки "aes256.h"     
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};  
//    Библиотека "aes256.h"   конец кода
//    Библиотека <Crypto.h> <AES.h>  начало кода
#include <Crypto.h>
#include <AES.h>
AES256 aes256;
uint8_t  buffer_1[16];   
uint8_t  buffer_2[16];     
uint8_t* buffer_3;    
uint8_t* buffer_4;     
uint8_t  buf[16];  
uint8_t  buf1[16];
//    Библиотека <Crypto.h> <AES.h>  конец кода
 
void Init_Key_AES(BlockCipher *cipher) {  // Функция инициализации шифрования и ключа (Библиотека <Crypto.h> <AES.h>)
    crypto_feed_watchdog();
    cipher->setKey(key, cipher->keySize());
}
 
uint8_t* Encrypt_AES(BlockCipher *cipher, uint8_t* Data1) {  // Функция шифрования AES256 (Библиотека <Crypto.h> <AES.h>)
    cipher->encryptBlock(buffer_1, Data1);
    return &buffer_1[0];
}
 
uint8_t* Decrypt_AES(BlockCipher *cipher, uint8_t* Data2)  {  // Функция расшифрования AES256 (Библиотека <Crypto.h> <AES.h>)
    cipher->decryptBlock(buf, Data2);
    return &buf[0];
}
 
void setup() {
  Serial.begin(19200);     delay(1000);
//    Библиотека "aes256.h"   начало кода
  unsigned long start_1;    unsigned long start_2;    unsigned long start_3;
  unsigned long start_4;    unsigned long start_5;    unsigned long start_6;
  unsigned long elapsed_1;  unsigned long elapsed_2;  unsigned long elapsed_3;  
  unsigned long elapsed_4;  unsigned long elapsed_5;  unsigned long elapsed_6;  
  Serial.println("  ");
  
  Serial.println("Тест библиотеки aes256.h");
  Serial.print("Открытые данные в HEX:       ");
  for (a = 0; a < 16; a++){
     Serial.print(Data[a], HEX); Serial.print(" ");
  }
  Serial.println("  ");
  
  start_1 = micros();
  aes256_init(&ctxt, key);                // команда библиотеки "aes256.h"     
  elapsed_1 = micros() - start_1;
  start_2 = micros();
  aes256_encrypt_ecb(&ctxt, Data);       // команда библиотеки "aes256.h"     
  elapsed_2 = micros() - start_2;
  
  Serial.print("Зашифрованные данные в HEX:  ");
  for (a = 0; a < 16; a++){
     Serial.print(Data[a], HEX); Serial.print(" ");
  }
  Serial.println("   ");
  
  start_3 = micros();
  aes256_decrypt_ecb(&ctxt, Data);      // команда библиотеки "aes256.h"     
  elapsed_3 = micros() - start_3;
  
  Serial.print("Расшифрованные данные в HEX: ");
  for (a = 0; a < 16; a++){
     Serial.print(Data[a], HEX); Serial.print(" ");
  }
  Serial.println("   ");
  
  Serial.print("Задержка на инициализацию ключа:   ");  Serial.print(elapsed_1);  Serial.println(" мкс");
  Serial.print("Задержка на шифрование:            ");  Serial.print(elapsed_2);  Serial.println(" мкс");
  Serial.print("Задержка на расшифрование:         ");  Serial.print(elapsed_3);  Serial.println(" мкс");
  Serial.println("   ");
//    Библиотека "aes256.h"   конец кода
 
//    Библиотека <Crypto.h> <AES.h>  начало кода
  start_4 = micros();
  Init_Key_AES(&aes256);
  elapsed_4 = micros() - start_4;
  Serial.println("Тест библиотеки Crypto.h, AES.h");
  
  Serial.print("Открытые данные в HEX:       ");
  for (a = 0; a < 16; a++){
     Serial.print(Data[a], HEX); Serial.print(" ");
  }
  Serial.println("  ");
 
  start_5 = micros();
  buffer_3 = Encrypt_AES(&aes256, Data);
  elapsed_5 = micros() - start_5;
 
  Serial.print("Зашифрованные данные в HEX:  ");
  for (a = 0; a < 16; a++){
     Serial.print(buffer_3[a], HEX); Serial.print(" ");
  }
  Serial.println("   ");
 
  start_6 = micros();
  buffer_4 = Decrypt_AES(&aes256, buffer_3);
  elapsed_6 = micros() - start_6;
 
  Serial.print("Расшифрованные данные в HEX: ");
  for (a = 0; a < 16; a++){
     Serial.print(buffer_4[a], HEX); Serial.print(" ");
  }
  Serial.println("   ");
 
  Serial.print("Задержка на инициализацию ключа:   ");  Serial.print(elapsed_4);  Serial.println(" мкс");
  Serial.print("Задержка на шифрование:            ");  Serial.print(elapsed_5);  Serial.println(" мкс");
  Serial.print("Задержка на расшифрование:         ");  Serial.print(elapsed_6);  Serial.println(" мкс");
 
//    Библиотека <Crypto.h> <AES.h>  конец кода
}
 
void loop() {
 
}
А вот код, который я написал для своих целей:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// Библиотека I2S
#include <driver/i2s.h>
const int sample_rate = 32000;
esp_err_t err1;   esp_err_t err2;
int buf_len = 64;
char *buf = (char*) calloc(buf_len, sizeof(char));
 
// Библиотека шифрования <Crypto.h> <AES.h>
uint8_t Data[] = { // Данные - 32 символа     
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};  
uint8_t key[] = { // Ключ шифрования - 32 символа     
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};  
#include <Crypto.h>
#include <AES.h>
AES256 aes256;             int a;
//uint8_t  buffer_1[16];     
//uint8_t* buffer_2;      uint8_t* buffer_3;    // uint8_t  buffer_4[16];
 
//uint8_t *BlockA = (uint8_t* ) malloc(sizeof(uint8_t)*16);
//uint8_t *BlockB = (uint8_t* ) malloc(sizeof(uint8_t)*buf_len);
 
   uint8_t* BlockC;   
//uint8_t *BlockC = (uint8_t*) calloc(buf_len, sizeof(uint8_t));
   uint8_t* BlockD;   
//uint8_t *BlockD = (uint8_t*) calloc(buf_len, sizeof(uint8_t));
 
void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.println("  ");  Serial.println("Setup I2S ...");    Serial.println("  "); 
  delay(1000);
  i2s_install();
  i2s_setpin();
  delay(500);
//  Init_Key_AES(&aes256); // Инициализация библиотеки и ключа шифрования
}
 
void loop() {
   Init_Key_AES(&aes256);
   int bytes_read = 0;
   
   while(bytes_read == 0) {
      bytes_read = i2s_read_bytes(I2S_NUM_1, buf, buf_len, 0);
   }
   //uint8_t* BlockC;   
   BlockC = AES_ENcrypt_to(Data,   buf_len);    // - функция шифрования массива, размер которого должен быть кратен 16
//delay(1);
   //uint8_t* BlockD;   
   BlockD = AES_DEcrypt_to(BlockC, buf_len);    // - функция расшифрования массива, размер которого должен быть кратен 16
 
   i2s_write_bytes(I2S_NUM_0, buf, bytes_read, portMAX_DELAY);
//   free(BlockC);
//   free(BlockD);
}
 
void Init_Key_AES(BlockCipher *cipher) {  // Функция инициализации шифрования и ключа (Библиотека <Crypto.h> <AES.h>)
    crypto_feed_watchdog();
    cipher->setKey(key, cipher->keySize());
}
 
uint8_t* Encrypt_AES(BlockCipher *cipher, uint8_t* Data1) {  // Функция шифрования AES256 (Библиотека <Crypto.h> <AES.h>)
//    uint8_t *buffer_1 = (uint8_t* ) malloc(sizeof(uint8_t) * 16);
    uint8_t  buffer_1[16];
    cipher->encryptBlock(buffer_1, Data1);
    return &buffer_1[0];
//    free(buffer_1);
}
 
uint8_t* Decrypt_AES(BlockCipher *cipher, uint8_t* Data2)  {  // Функция расшифрования AES256 (Библиотека <Crypto.h> <AES.h>)
//    uint8_t *buffer_4 = (uint8_t* ) malloc(sizeof(uint8_t) * 16);
    uint8_t  buffer_4[16];
    cipher->decryptBlock(buffer_4, Data2);
    return &buffer_4[0];
//    free(buffer_4);
}
 
uint8_t* AES_ENcrypt_to(uint8_t* Data_t, int buf_len_t) {
   uint8_t BlockA[16];
   uint8_t BlockB[32];
//   uint8_t *BlockA = (uint8_t* ) malloc(sizeof(uint8_t) * 16);
//   uint8_t *BlockB = (uint8_t* ) malloc(sizeof(uint8_t) * buf_len_t );
   uint8_t* buffer_2;
   int blockCode = buf_len_t/16;   // считаем на сколько блоков нужно разбить данные
   int blockCodeAES;
   if (buf_len_t%16 == 0){
    blockCodeAES = blockCode;   // - считаем на сколько блоков нужно разбить данные
   }
   else if (buf_len_t%16 != 0){
    Serial.println("Разбито с остатком! ОШИБКА! Размер входного массива не кратен 16-ти"); 
   }
   int i; int b; int g = 0; int d; int v = 0;
   for (i = 0; i < blockCodeAES; i++){
    for (b = 0; b < 16; b++){
      g = b + 16*i;
      BlockA[b] = Data_t[g];   // 
      }
//    uint8_t* buffer_2;
    buffer_2 = Encrypt_AES(&aes256, BlockA);
    for (d = 0; d < 16; d++){
      v = d + 16*i;
      BlockB[v] = buffer_2[d];
    }
   }
return &BlockB[0];
 
//free(BlockA);  
//free(BlockB);
//free(buffer_2);
}
 
uint8_t* AES_DEcrypt_to(uint8_t* Data_r, int buf_len_r){
   uint8_t BlockA[16];
   uint8_t BlockB[32];
//   uint8_t *BlockA = (uint8_t* ) malloc(sizeof(uint8_t) * 16);
//   uint8_t *BlockB = (uint8_t* ) malloc(sizeof(uint8_t) * buf_len_r);
   uint8_t* buffer_3;
   int blockCode = buf_len_r/16;   // считаем на сколько блоков нужно разбить данные
   int blockCodeAES;
   if (buf_len_r%16 == 0){
    blockCodeAES = blockCode;   // - считаем на сколько блоков нужно разбить данные
   }
   else if (buf_len_r%16 != 0){
    Serial.println("Разбито с остатком! ОШИБКА! Размер входного массива не кратен 16-ти"); 
   }
   int i; int b; int g = 0; int d; int v = 0; 
   for (i = 0; i < blockCodeAES; i++){
    for (b = 0; b < 16; b++){
      g = b + 16*i;
      BlockA[b] = Data_r[g];  
      }
    buffer_3 = Decrypt_AES(&aes256, BlockA);
    for (d = 0; d < 16; d++){
      v = d + 16*i;
      BlockB[v] = buffer_3[d];
    }
   }
return &BlockB[0];
 
//free(BlockA);  
//free(BlockB);
//free(buffer_3);
}
 
void i2s_install(){
    /* TX: I2S_NUM_0 */
  const i2s_config_t i2s_config_tx = {
    .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX),
    .sample_rate = sample_rate,
    .bits_per_sample = i2s_bits_per_sample_t(16),
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // default interrupt priority
    .dma_buf_count = 32,
    .dma_buf_len = buf_len,  // 2
     // .use_apll = false,
     // .tx_desc_auto_clear = false,  // I2S автоматически очищает дескриптор tx, если есть состояние недостаточного заполнения (помогает избежать шума в случае недоступности данных)
     // .fixed_mclk = 0 // I2S с использованием фиксированного выхода MCLK. Если use_apll = true и fixed_mclk> 0, то выходной сигнал часов для i2s фиксирован и равен значению fixed_mclk.
  };
  err1 = i2s_driver_install(I2S_NUM_0, &i2s_config_tx, 0, NULL);
  if (err1 != ESP_OK) {
  Serial.printf("Failed installing driver_1: %d\n", err1);
  while (true);
  }
       /* RX: I2S_NUM_1 */
  const i2s_config_t i2s_config_rx = {
    .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = sample_rate,
    .bits_per_sample = i2s_bits_per_sample_t(16), //32
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // default interrupt priority
    .dma_buf_count = 32,    // 32
    .dma_buf_len = buf_len,  //32*2
     // .use_apll = false,
     // .tx_desc_auto_clear = false,  // I2S автоматически очищает дескриптор tx, если есть состояние недостаточного заполнения (помогает избежать шума в случае недоступности данных)
     // .fixed_mclk = 0 // I2S с использованием фиксированного выхода MCLK. Если use_apll = true и fixed_mclk> 0, то выходной сигнал часов для i2s фиксирован и равен значению fixed_mclk.
  };
  err2 = i2s_driver_install(I2S_NUM_1, &i2s_config_rx, 0, NULL);
  if (err2 != ESP_OK) {
  Serial.printf("Failed installing driver_2: %d\n", err2);
  while (true);
  }
  Serial.println("I2S driver installed.");
}
 
void i2s_setpin(){
     /* TX: I2S_NUM_0 */
  const i2s_pin_config_t pin_config_tx = {
    .bck_io_num =   26,
    .ws_io_num =    25,
    .data_out_num = 22,
    .data_in_num =  I2S_PIN_NO_CHANGE  };
    
    err1 = i2s_set_pin(I2S_NUM_0, &pin_config_tx);
    if (err1 != ESP_OK) {
    Serial.printf("Failed setting pin_1: %d\n", err1);
    while (true);
    }
    /* RX: I2S_NUM_1 */
  const i2s_pin_config_t pin_config_rx = {
    .bck_io_num =   17,
    .ws_io_num =    27,
    .data_out_num = I2S_PIN_NO_CHANGE,
    .data_in_num =  33  };
 
    err2 = i2s_set_pin(I2S_NUM_1, &pin_config_rx);
    if (err2 != ESP_OK) {
    Serial.printf("Failed setting pin_2: %d\n", err2);
    while (true);
    }
  Serial.println("I2S pins installed.");
}
Компиляция проходит нормально и ESP32 прошивается, но как начинает работать постоянно перезагружается. Я уже по разному менял, но перезагрузка все равно происходит.
У меня большие подозрения, что это связано в выделением памяти и объявлением массивов. Проверял шифрование отдельно - все работает хорошо (и шифрует и расшифровывает).
Посмотрите пожалуйста в этом отношении, может где-то не в том месте объявил массив или не должным образом.

Добавлено через 22 минуты
Если закомментировать строку 59 ->
Code
1
BlockD = AES_DEcrypt_to(BlockC, buf_len);    // - функция расшифрования массива, размер которого должен быть кратен 16
то по крайней мере ничего не перезагружается, но и, соответственно, не расшифровывается.
0
Эксперт по электронике
6998 / 3314 / 341
Регистрация: 28.10.2011
Сообщений: 13,024
Записей в блоге: 7
29.06.2021, 12:27
Цитата Сообщение от mike84 Посмотреть сообщение
работаю в Arduino IDE, и под неё не нашел подходящих библиотек
Библиотеки это код, кем-то написанный. Пишите код сами.
Цитата Сообщение от mike84 Посмотреть сообщение
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
uint8_t* Encrypt_AES(BlockCipher *cipher, uint8_t* Data1) {  // Функция шифрования AES256 (Библиотека <Crypto.h> <AES.h>)
//    uint8_t *buffer_1 = (uint8_t* ) malloc(sizeof(uint8_t) * 16);
    uint8_t  buffer_1[16];
    cipher->encryptBlock(buffer_1, Data1);
    return &buffer_1[0];
//    free(buffer_1);
}
uint8_t* Decrypt_AES(BlockCipher *cipher, uint8_t* Data2)  {  // Функция расшифрования AES256 (Библиотека <Crypto.h> <AES.h>)
//    uint8_t *buffer_4 = (uint8_t* ) malloc(sizeof(uint8_t) * 16);
    uint8_t  buffer_4[16];
    cipher->decryptBlock(buffer_4, Data2);
    return &buffer_4[0];
//    free(buffer_4);
}
То есть вы создаете локальный массив которой существует пока выполняется функция и возвращаете указатель на него? Сделайте массив статическим.
1
3 / 3 / 0
Регистрация: 02.01.2016
Сообщений: 160
29.06.2021, 14:54  [ТС]
Цитата Сообщение от locm Посмотреть сообщение
Библиотеки это код, кем-то написанный. Пишите код сами.
Спасибо, стараюсь, но я пока не такой гуру...
Цитата Сообщение от locm Посмотреть сообщение
То есть вы создаете локальный массив которой существует пока выполняется функция и возвращаете указатель на него? Сделайте массив статическим.
Думаю сделал то, о чем вы сказали.

Ура! Спасибо! Все получилось!!! Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
// Библиотека I2S
#include <driver/i2s.h>
const int sample_rate = 32000;
esp_err_t err1;   esp_err_t err2;
uint16_t buf_len = 64; 
uint8_t *buf = (uint8_t*) calloc(buf_len, sizeof(uint8_t));
 
// Библиотека шифрования <Crypto.h> <AES.h>
uint8_t Data[] = { // Данные - 32 символа     
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x1d, 0x1e, 0x1f,
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x1d, 0x1e, 0x1f};  
uint8_t key[] = { // Ключ шифрования - 32 символа     
                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; 
#include <Crypto.h>
#include <AES.h>
AES256 aes256;             int a;
uint8_t  buffer_1[16];     uint8_t  buffer_4[16];
 
uint8_t BlockA[16];
uint8_t *BlockB = (uint8_t* ) malloc(sizeof(uint8_t)*buf_len);
uint8_t BlockE[16];
uint8_t *BlockF = (uint8_t* ) malloc(sizeof(uint8_t)*buf_len);
 
uint8_t* BlockC;   
uint8_t* BlockD;   
 
void setup() {
  Serial.begin(500000);
  delay(100);
  Serial.println("  ");  Serial.println("Setup I2S ...");    Serial.println("  "); 
  delay(1000);
  i2s_install();
  i2s_setpin();
  delay(500);
  Init_Key_AES(&aes256); // Инициализация библиотеки и ключа шифрования
  
   xTaskCreate(     vTask1,        
                    "vTask1",    
                    10000,         
                    NULL,          
                    1,           
                    NULL);          
   xTaskCreate(     vTask2,        
                    "vTask2",      
                    10000,            
                    NULL,             
                    2,                
                    NULL);     
}
 
void vTask1( void * pvParameters ) {
   for( ;; ){
   Serial.println("Обработка задания vTask_1");   vTaskDelay( pdMS_TO_TICKS( 1000 ) );
   
   Serial.print("buf:  ");
   for (a = 0; a < buf_len; a++){
      Serial.print(buf[a], DEC); Serial.print(" ");
   }
   Serial.println("  ");
 
   Serial.print("Шифр: ");
   for (a = 0; a < buf_len; a++){
      Serial.print(BlockC[a], DEC); Serial.print(" ");
   }
   Serial.println("  ");
 
   Serial.print("Откр: ");
   for (a = 0; a < buf_len; a++){
      Serial.print(BlockD[a], DEC); Serial.print(" ");
   }
   Serial.println("  "); Serial.println("  ");
   
    }
}
 
void vTask2( void * pvParameters) {
    for( ;; ){
    Serial.println("Обработка задания vTask_2");    vTaskDelay( pdMS_TO_TICKS( 1000 ) );
    } 
}
 
void loop() {
   int bytes_read = 0;
 
   while(bytes_read == 0) {
      bytes_read = i2s_read_bytes(I2S_NUM_1, buf, buf_len, 0);
   }
 
   BlockC = AES_ENcrypt_to(&aes256, buf,   buf_len);    // - функция шифрования массива, размер которого должен быть кратен 16
 
   BlockD = AES_DEcrypt_to(&aes256, BlockC, buf_len);    // - функция расшифрования массива, размер которого должен быть кратен 16
 
   i2s_write_bytes(I2S_NUM_0, BlockD, bytes_read, portMAX_DELAY);
}
 
void Init_Key_AES(BlockCipher *cipher) {  // Функция инициализации шифрования и ключа (Библиотека <Crypto.h> <AES.h>)
    crypto_feed_watchdog();
    cipher->setKey(key, cipher->keySize());
}
 
uint8_t* AES_ENcrypt_to(BlockCipher *cipher, uint8_t* Data_t, uint16_t buf_len_t) {
   int blockCode = buf_len_t/16;   // считаем на сколько блоков нужно разбить данные
   int blockCodeAES;
   if (buf_len_t%16 == 0){
    blockCodeAES = blockCode;   // - считаем на сколько блоков нужно разбить данные
   }
   else if (buf_len_t%16 != 0){
    Serial.println("Разбито с остатком! ОШИБКА_1! Размер входного массива не кратен 16-ти"); 
   }
   int i; int b; int g = 0; int d; int v = 0;
   for (i = 0; i < blockCodeAES; i++){
    for (b = 0; b < 16; b++){
      g = b + 16*i;
      BlockA[b] = Data_t[g];   // 
      }
    cipher->encryptBlock(buffer_1, BlockA);
    for (d = 0; d < 16; d++){
      v = d + 16*i;
      BlockB[v] = buffer_1[d];
    }
   }
return &BlockB[0];
}
 
uint8_t* AES_DEcrypt_to(BlockCipher *cipher, uint8_t* Data_r, uint16_t buf_len_r){
   int blockCode = buf_len_r/16;   // считаем на сколько блоков нужно разбить данные
   int blockCodeAES;
   if (buf_len_r%16 == 0){
    blockCodeAES = blockCode;   // - считаем на сколько блоков нужно разбить данные
   }
   else if (buf_len_r%16 != 0){
    Serial.println("Разбито с остатком! ОШИБКА_2! Размер входного массива не кратен 16-ти"); 
   }
   int i; int b; int g = 0; int d; int v = 0; 
   for (i = 0; i < blockCodeAES; i++){
    for (b = 0; b < 16; b++){
      g = b + 16*i;
      BlockE[b] = Data_r[g];
      }
    cipher->decryptBlock(buffer_4, BlockE);
    for (d = 0; d < 16; d++){
      v = d + 16*i;
      BlockF[v] = buffer_4[d];
    }
   }
return &BlockF[0];
}
 
void i2s_install(){
    /* TX: I2S_NUM_0 */
  const i2s_config_t i2s_config_tx = {
    .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX),
    .sample_rate = sample_rate,
    .bits_per_sample = i2s_bits_per_sample_t(16),
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // default interrupt priority
    .dma_buf_count = 32,
    .dma_buf_len = buf_len,  // 2
     // .use_apll = false,
     // .tx_desc_auto_clear = false,  // I2S автоматически очищает дескриптор tx, если есть состояние недостаточного заполнения (помогает избежать шума в случае недоступности данных)
     // .fixed_mclk = 0 // I2S с использованием фиксированного выхода MCLK. Если use_apll = true и fixed_mclk> 0, то выходной сигнал часов для i2s фиксирован и равен значению fixed_mclk.
  };
  err1 = i2s_driver_install(I2S_NUM_0, &i2s_config_tx, 0, NULL);
  if (err1 != ESP_OK) {
  Serial.printf("Failed installing driver_1: %d\n", err1);
  while (true);
  }
       /* RX: I2S_NUM_1 */
  const i2s_config_t i2s_config_rx = {
    .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = sample_rate,
    .bits_per_sample = i2s_bits_per_sample_t(16), //32
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // default interrupt priority
    .dma_buf_count = 32,    // 32
    .dma_buf_len = buf_len,  //32*2
     // .use_apll = false,
     // .tx_desc_auto_clear = false,  // I2S автоматически очищает дескриптор tx, если есть состояние недостаточного заполнения (помогает избежать шума в случае недоступности данных)
     // .fixed_mclk = 0 // I2S с использованием фиксированного выхода MCLK. Если use_apll = true и fixed_mclk> 0, то выходной сигнал часов для i2s фиксирован и равен значению fixed_mclk.
  };
  err2 = i2s_driver_install(I2S_NUM_1, &i2s_config_rx, 0, NULL);
  if (err2 != ESP_OK) {
  Serial.printf("Failed installing driver_2: %d\n", err2);
  while (true);
  }
  Serial.println("I2S driver installed.");
}
 
void i2s_setpin(){
     /* TX: I2S_NUM_0 */
  const i2s_pin_config_t pin_config_tx = {
    .bck_io_num =   26,
    .ws_io_num =    25,
    .data_out_num = 22,
    .data_in_num =  I2S_PIN_NO_CHANGE  };
    
    err1 = i2s_set_pin(I2S_NUM_0, &pin_config_tx);
    if (err1 != ESP_OK) {
    Serial.printf("Failed setting pin_1: %d\n", err1);
    while (true);
    }
    /* RX: I2S_NUM_1 */
  const i2s_pin_config_t pin_config_rx = {
    .bck_io_num =   17,
    .ws_io_num =    27,
    .data_out_num = I2S_PIN_NO_CHANGE,
    .data_in_num =  33  };
 
    err2 = i2s_set_pin(I2S_NUM_1, &pin_config_rx);
    if (err2 != ESP_OK) {
    Serial.printf("Failed setting pin_2: %d\n", err2);
    while (true);
    }
  Serial.println("I2S pins installed.");
}
buf - считанный буфер с микрофона по I2S;
BlockC - зашифрованный буфер;
BlockD - расшифрованный буфер, который отправляем по I2S на ЦАП.

Если сделать как написано, то расшифрованный звук отлично слышен на ЦАПе. А вот если на ЦАП послать зашифрованный звук, т.е. буфер BlockC , то в динамике слышен равномерный шум, который не влияет от "говорения" в микрофон.
Т.е. если buf (отсчеты звука с микрофона) или BlockD (расшифрованные отсчеты звука) направить по I2S на ЦАП, то звук отличный. Если по I2S на ЦАП направить зашифрованный буфер - BlockC, то в динамике сплошной равномерный шум, который не зависит от звуковых волн, направляемых на микрофон.
Вопрос: почему я в динамике ЦАПа слышу сплошной равномерный шум? почему он пропорционально не изменяется с тем, как я говорю в микрофон?
Или отсчеты после шифрования принимают какие-то значения, что вызывают в ЦАПе этот шум?
0
4084 / 2689 / 590
Регистрация: 11.09.2009
Сообщений: 9,577
29.06.2021, 17:28
Цитата Сообщение от mike84 Посмотреть сообщение
Вопрос: почему я в динамике ЦАПа слышу сплошной равномерный шум?
Неожиданный вопрос, особенно после такого длительного обсуждения... Так "звучит" зашифрованный сигнал. Вы же его для того и шифруете, чтобы без расшифровки невозможно было ничего разобрать?
Или вы совсем не понимаете, что вы делаете?
0
3 / 3 / 0
Регистрация: 02.01.2016
Сообщений: 160
29.06.2021, 17:31  [ТС]
Цитата Сообщение от i8085 Посмотреть сообщение
Неожиданный вопрос, особенно после такого длительного обсуждения... Так "звучит" зашифрованный сигнал. Вы же его для того и шифруете, чтобы без расшифровки невозможно было ничего разобрать?
Или вы совсем не понимаете, что вы делаете?
Прочтите внимательно ВСЁ что я написал, а не отрывок! И тогда пожалуйста ответьте по сути.
0
4084 / 2689 / 590
Регистрация: 11.09.2009
Сообщений: 9,577
29.06.2021, 21:04
Цитата Сообщение от mike84 Посмотреть сообщение
Прочтите внимательно ВСЁ ... и ответьте по сути
Я внимательно прочитал вашу преамбулу к вопросу и сам вопрос. Между строк читать не умею.
Ответ был строго по сути вопроса
Цитата Сообщение от mike84 Посмотреть сообщение
Вопрос: почему я в динамике ЦАПа слышу сплошной равномерный шум?
Потому что зашифрованный сигнал - это равномерный шум. Могу добавить на
Цитата Сообщение от mike84 Посмотреть сообщение
почему он пропорционально не изменяется с тем, как я говорю в микрофон?
Потому что шифрование специально делается так, чтобы в зашифрованном не осталось никаких признаков исходного сигнала. Поэтому что есть сигнал, что ноль на входе, - на выходе шифратора будет одинаковый по спектральным характеристикам шумоподобный сигнал. Что вы и наблюдаете:
Цитата Сообщение от mike84 Посмотреть сообщение
Если по I2S на ЦАП направить зашифрованный буфер - BlockC, то в динамике сплошной равномерный шум, который не зависит от звуковых волн, направляемых на микрофон.
0
3 / 3 / 0
Регистрация: 02.01.2016
Сообщений: 160
29.06.2021, 21:35  [ТС]
Цитата Сообщение от i8085 Посмотреть сообщение
Ответ был строго по сути вопроса
Честно говоря Ваш ответ был смешной. Типа я написал этот код, но ничего не понимаю)))) Как тогда я это написал?
На такие подобные смешные комментарии я всегда говорю: "Напишите лучше, тогда и поговорим!" Конечно Вы скажите: "Да зачем мне это нужно еще что-то писать?". А я Вам отвечу: "Тогда не зачем писать подобную Вашу ерунду!".

На самом деле вопрос был конкретный, а именно в отношении равномерного шума, не изменяющегося по мере вещания в микрофон. А Вы выхватили
Цитата Сообщение от i8085 Посмотреть сообщение
почему я в динамике ЦАПа слышу сплошной равномерный шум?
и рады)))

Цитата Сообщение от i8085 Посмотреть сообщение
Потому что шифрование специально делается так, чтобы в зашифрованном не осталось никаких признаков исходного сигнала. Поэтому что есть сигнал, что ноль на входе, - на выходе шифратора будет одинаковый по спектральным характеристикам шумоподобный сигнал.
Вы глубоко занимались шифрованием, что знаете такие подробности? Вы это по отношению к любому шифру имеете ввиду или только AES256?
Пример_1 и Пример_2. Возьмите эти два онлайн примера и Вы поймете, что то, что Вы писали в отношении одинакового сигнала на выходе - некорректно... Как тогда по Вашему по одинаковому сигналу будет проходить расшифрование? В приведенных примерах четко показано что это не так. Можно ввести самостоятельно и сам исходный текст и ключ, зашифровать и расшифровать. Ничего подобного, о чем Вы пишите, там и близко нет.
0
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
30.06.2021, 14:25
Цитата Сообщение от mike84 Посмотреть сообщение
Voland_ - вы вначале прочитайте внимательно, просмотрите код, ну а потом уже ..... ля-ля....
Цитата Сообщение от mike84 Посмотреть сообщение
заканчивайте заполнять тему пустой информацией! Толку с того, что вы пишите... одни препирательства.
Цитата Сообщение от mike84 Посмотреть сообщение
А я Вам отвечу: "Тогда не зачем писать подобную Вашу ерунду!".
mike84, продолжайте в том же тоне . Хамская беседа так и подталкивает людей заниматься вашими вопросами

Цитата Сообщение от i8085 Посмотреть сообщение
Потому что шифрование специально делается так, чтобы в зашифрованном не осталось никаких признаков исходного сигнала. Поэтому что есть сигнал, что ноль на входе, - на выходе шифратора будет одинаковый по спектральным характеристикам шумоподобный сигнал.
пока не соглашусь. У вас есть где-то статья или цитата на этот счет? Я нигде не встречал анализ эллиптических видов кодирования на предмет их "частотных характеристик" Я уверен, этот вопрос может существовать, но не знаю, где об этом что-то сказано...
0
4084 / 2689 / 590
Регистрация: 11.09.2009
Сообщений: 9,577
30.06.2021, 15:46
Цитата Сообщение от Voland_ Посмотреть сообщение
пока не соглашусь. У вас есть где-то статья или цитата на этот счет?
Я не пытаюсь настаивать.
Соображение очень простое. Алгоритм шифрования никак не зависит от содержимого входного потока данных. Ему всё равно, что отсчёты звука, что нули...
А если алгоритм при потоке нулей на входе выдаёт на выходе поток нулей, то это очень плохой алгоритм шифрования.

Цитата Сообщение от Voland_ Посмотреть сообщение
Хамская беседа так и подталкивает людей заниматься вашими вопросами
Уже решил этот вопрос очень просто - при помощи "Списка игнорирования".
1
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
30.06.2021, 16:21
Цитата Сообщение от i8085 Посмотреть сообщение
если алгоритм при потоке нулей на входе выдаёт на выходе поток нулей, то это очень плохой алгоритм шифрования.
ну, это да. Просто любое шифрование для чего-то нужно и имеет разные свойства. Допустим, любой кодек либо архиватор тожно можно рассматривать в качестве шифратора. И можно привести довольно много других примеров шифрования ( в том числе - свертки ), если рассматривать в широком смысле. И в этом случае - AES - это один из семейства "эллиптических кривых", имеющий весьма конкретные свойства.

Цитата Сообщение от i8085 Посмотреть сообщение
Списка игнорирования
...об этом как-то не подумал. Просто решил игнорить пассивно А идея ваша вполне годная
0
30.06.2021, 23:56

Не по теме:

Цитата Сообщение от Voland_ Посмотреть сообщение
А идея ваша...
Это не моя идея. Это функция форума: Профиль->Кабинет->Настройки и параметры->Список игнорирования.

0
1 / 1 / 0
Регистрация: 07.11.2023
Сообщений: 2
07.11.2023, 21:02
Осмелюсь заметить, что из того обстоятельства что, зашифрованный звуковой сигнал воспринимается нашим слухом как шум отнюдь не следует что зашифрованная "тишина" то же шумит. В данном конкретном случае если на вход шифратора AES подавать массив состоящий из "0", на выходе получается некоторая периодическая последовательность, периодичность которой видимо зависит от длинны ключа и других параметров шифрования. Именно на это пытался видимо обратить внимание miki86 ссылаясь на Пример1 и 2. На слух такая последовательность воспринимается как однородный тон. Причиной же шума который miki86 слышал в закодированном канале вместо тона, являются закодированные собственные шумы I2S микрофона, поскольку микрофон он не отсоединял от шины i2s, а просто в него не говорил.
1
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
07.11.2023, 22:19
Цитата Сообщение от ABC1958 Посмотреть сообщение
зашифрованный звуковой сигнал воспринимается нашим слухом как шум отнюдь не следует что зашифрованная "тишина" то же шумит.
давайте определимся что такое тишина.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.11.2023, 22:19

Ввод и вывод структуры используя файлы
Помогите пожалуйста написать структуру используя файлы на С++. Очень срочно помогите пожалуйста !!! Организовать ввод и вывод...

Ввод и вывод структуры используя файлы
Организовать ввод и вывод данных структуры (не менее 10 записей), используя файлы. Используя поля созданной структуры, выполнить выборку...

Ввод/вывод данных организовать, используя книгу Excel
Здравствуйте Ввод/вывод данных организовать, используя книгу Excel. Дан одномерный массив.Найти номер последнего ненулевого ...

Ввод и вывод строк осуществлять, используя функции gets и puts
Задана строка, содержащая целые числа и слова, разделенные пробелами (одним или несколькими). Определить сумму целых чисел в строке. ...

Расчет по формуле. Ввод и вывод, используя текстовые поля
Помогите пожалуста!Нужно сделать прогу которая рассчитывает значение по формуле : x=100/ n +y , значения n,m должны вводиться через...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru