Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
артист
94 / 20 / 20
Регистрация: 17.09.2014
Сообщений: 1,186
Завершенные тесты: 2
1

Как скопировать часть массива WCHAR в массив BYTE?

05.01.2016, 07:02. Просмотров 1082. Ответов 11
Метки нет (Все метки)

Пытаюсь зашифровать строку в AES.

wTextIn - исходный текст
wTextOut - шифрованный

C++
1
2
3
byte bDataBlocks[crypto.block_size] = {0};      // Буффер
WCHAR * wTextIn = new WCHAR[eLen[0]];           // Массив под текст(ввод)
WCHAR * wTextOut = new WCHAR[eLen[0] + 16];     // Массив под текст(вывод)
C++
1
2
3
4
5
6
7
8
9
unsigned chunk = 0; // Счётчик. + 16 - для записи потому, что записан 1й блок
 
while(chunk < eLen[0]) // Цикл по строке
{
    std::copy(wTextIn + chunk, wTextIn + chunk + 16, reinterpret_cast<WCHAR *>(bDataBlocks));   // Копировать текст по 16 байт в буффер
    (crypto.*whats_to_do)(bDataBlocks, bDataBlocks);                // Шифровать блок
    memcpy(wTextOut[chunk + 16], bDataBlocks, 16 * sizeof(BYTE));   // Записать 1й блок
    chunk += 16; // Прибавлять по 16
}
Не могу сделать чтобы копировало по 16 байт.

На данный момент вот тут только ошибка(явная):
C++
1
wTextOut[chunk + 16]
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.01.2016, 07:02
Ответы с готовыми решениями:

Std::copy как скопировать часть строки массива byte?
Вот из этой строки: BYTE pbHash; Нужно скопировать содержимое с 0й по 15ю...

Преобразовать тип данных char[] -> wchar -> BYTE для структуры DATA_BLOB crypt32.dll
Помогите, пожалуйста, написать за меня: 1) преобразование аргумента ком....

Как скопировать символ из символьного массива в другой массив
Есть массив s и r в обоих по 8 символов + \0 (окончание строки). В s есть...

Как скопировать часть строки до определенного символа?
Допустим, пользователь вводит с клавиатуры строку. Необходимо скопировать часть...

Скопировать часть строки и часть удалить
1. Удалить из строки ее часть с заданной позиции и заданной длины. 2....

11
артист
94 / 20 / 20
Регистрация: 17.09.2014
Сообщений: 1,186
Завершенные тесты: 2
06.01.2016, 22:58  [ТС] 2
Ну по любому можно же как - то...

А если так:
eLen[0] - длина текста в поле.

Вот есть текст из поля edit в wchar:
C++
1
2
WCHAR * wTextIn = new WCHAR[eLen[0]];           // Массив под текст(ввод)
GetWindowTextW(hEdit[1], wTextIn, eLen[0] + 1); // Считать текст из поля
Теперь весь этот текст скопировать в строку byte:
C++
1
2
BYTE * bData = new BYTE[eLen[0] * 2];           // Массив под данные(ввод)
std::copy(wTextIn, wTextIn + eLen[0], reinterpret_cast<WCHAR *>(bData));    // Копировать двух байтовую строку в массив байт
Далее мне нужно зашифровать этот массив.
Можно(так проще наверное) просто дёргать из этого массива по 16 байт в массив-буффер, далее в буфере шифровать и вставлять шифрованные байты обратно в массив.

Как скопировать из массива например с 32й по 48ю ячейку?
Вот в этот буфер:
C++
1
BYTE bDataBlocks[16] = {0};     // Буффер
0
артист
94 / 20 / 20
Регистрация: 17.09.2014
Сообщений: 1,186
Завершенные тесты: 2
10.01.2016, 18:45  [ТС] 3
Ну подскажите...

Всё на циклах сделал, ну вообще бред же:
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
BYTE bDataBlocks[crypto.block_size] = {0};      // Буффер для шифрования, 16 ячеек
 
WCHAR * wTextIn = new WCHAR[eLen[0]];           // Массив под текст(ввод)
GetWindowTextW(hEdit[1], wTextIn, eLen[0] + 1); // Получить текст из поля(без нуль терминатора)
 
BYTE * bDataIn = new BYTE[eLen[0] * 2];                                     // Массив под данные(ввод), в него копируется весь текст
std::copy(wTextIn, wTextIn + eLen[0], reinterpret_cast<WCHAR *>(bDataIn));  // Копировать двух байтовую строку в массив байт
 
BYTE * bDataOut = new BYTE[eLen[0] - ((eLen[0] % 16) - 16) * 2 + 16];       // Массив под данные(вывод), в него копируются шифрованные данные
 
unsigned long long llDataLenght = eLen[0];      // Длина всего текста
 
for(int i = 0; i < 8; ++i) bDataBlocks[i] = llDataLenght >> (i * 8); // Записать длину текста в буфер побайтово
 
(crypto.*whats_to_do)(bDataBlocks, bDataBlocks);    // Шифровать 1й блок
 
unsigned chunk = -1;    // Счётчик. потом + 16 - для записи потому, что записан 1й блок
 
while(++chunk < 16) bDataOut[chunk] = bDataBlocks[chunk];   // Копировать 1й блок
//memcpy(wTextOut, bDataBlocks, 16 * sizeof(BYTE)); // Записать 1й блок
 
while(chunk < eLen[0]) // Цикл, пока не кончатся данные
{
    for(int j = 0, i = (chunk - 16); i < chunk; ++i)    // Копировать данные по 16 байт в буффер
    {
        if(i < eLen[0]) // Если данные не кончились
        {
            bDataBlocks[i] = bDataIn[i];    // Копировать данные
            j++;                            // Считать скопированные данные
        }
        else if(j < 15) // Если данные кончились, а буффер заполнен не до конца
        {
            while(j < 16)   // Дополнить буффер до конца
            {
                bDataBlocks[j] = 0; // Записать ноль
                j++;                // Считать скопированные данные
            }
            break;  // Разрушить цикл копирования в буффер
        }
        else break; // Если данные закончились и буффер полностью забит, разрушить цикл копирования в буффер
    }
    (crypto.*whats_to_do)(bDataBlocks, bDataBlocks);    // Шифровать блок
    
    for(int i = chunk; i < (chunk += 16); ++i) bDataOut[chunk] = bDataBlocks[chunk];    // Копировать зашифрованный блок в массив вывода
}
0
nonedark2008
1051 / 785 / 220
Регистрация: 28.07.2012
Сообщений: 2,187
10.01.2016, 19:00 4
Лучший ответ Сообщение было отмечено артист как решение

Решение

Цитата Сообщение от артист Посмотреть сообщение
Всё на циклах сделал, ну вообще бред же
Уточни что откуда и куда ты хочешь копировать.
Почему именно по 16 байт?
Зачем ты используешь WCHAR? Это только добавляет тебе проблем, т.к. он занимает два байта памяти.
Возьми лучше обычный char и используй строки из латинских букв, после этого будет просто перейти к шифрованию произвольных данных.
1
артист
94 / 20 / 20
Регистрация: 17.09.2014
Сообщений: 1,186
Завершенные тесты: 2
10.01.2016, 19:59  [ТС] 5
Не, всё делаю в byte.
Считываю в wchar, и перевожу в byte.

Вот эту строку:
C++
1
BYTE * bDataIn = new BYTE[eLen[0] * 2];
Нужно копировать частями по 16 ячеек(байт) в этот буффер:
C++
1
BYTE bDataBlocks[crypto.block_size] = {0};
Т.е. сначала с 0й по 15ю ячейку, потом с 16й по 32ю, и т.д. пока не закончится строка.
0
Perfilov
264 / 164 / 56
Регистрация: 25.02.2015
Сообщений: 435
10.01.2016, 20:20 6
Лучший ответ Сообщение было отмечено артист как решение

Решение

похоже вы попутали арифметику с указателями.
например:
std::copy(wTextIn + 0, wTextIn + 16, reinterpret_cast<WCHAR *>(bDataBlocks));
вот это попытка закопировать 16 символов типа WCHAR в буффер. я так понял буфер на 16 байт.
а размер символа WCHAR_T - два байта. итого это попытка закопировать 32 байта в буфер с размеров в 16 байт.

ну и далее всякие индексные операции вроде
&wTextOut[16] - это 16 символ от начала строки. а вот в байтах смещение будет 16 * sizeof(*wTextOut), т.е. 32 байта,
т.к. тип символа - широкий
1
nonedark2008
1051 / 785 / 220
Регистрация: 28.07.2012
Сообщений: 2,187
10.01.2016, 20:46 7
Лучший ответ Сообщение было отмечено артист как решение

Решение

Цитата Сообщение от артист Посмотреть сообщение
Нужно копировать частями по 16 ячеек(байт) в этот буффер:
Это можно сделать так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Length; // Длина bDataIn 
unsigned NumOfBlocks = Length / 16; // Количество целых блоков
for (unsigned i = 0; i < NumOfBlocks; ++i) {
  memcpy(bDataBlocks, bDataIn + i * 16, sizeof(BYTE) * 16); // Копируем 16 байт i-го блока
  // Шифруем блок
}
 
unsigned LastBytes = Length % 16;
if (LastBytes) { // Если есть неполный блок
  memcpy(bDataBlocks, bDataIn + NumOfBlocks * 16, sizeof(BYTE) * LastBytes); // Копируем остаток
  memset(bDataBlocks + LastBytes, 0, sizeof(BYTE) * (16 - LastBytes)); // Дописываем нули в конец
  NumOfBlocks += 1;
  // Шифруем последний блок
}
1
артист
94 / 20 / 20
Регистрация: 17.09.2014
Сообщений: 1,186
Завершенные тесты: 2
10.01.2016, 22:09  [ТС] 8
Спасибо большое ))

А если нужно потом(после шифрования блока) вставить в другой массив с определённой ячейки, будет так?:

C++
1
memcpy(bDataOut + i + 16 * 16, bDataBlocks, sizeof(BYTE) * 16);
i + 16 - у меня уже записано в первые 16 ячеек блок, содержащий длину всех данных.

Правильно будет?
0
nonedark2008
1051 / 785 / 220
Регистрация: 28.07.2012
Сообщений: 2,187
10.01.2016, 22:18 9
Цитата Сообщение от артист Посмотреть сообщение
i + 16 * 16
Что это? oO
Если побайтно нужно скопировать N элементов из массива pA в массив pB со смещением i, то:
C++
1
memcpy(pB + i, pA, sizeof(pA[0]) * N);
1
артист
94 / 20 / 20
Регистрация: 17.09.2014
Сообщений: 1,186
Завершенные тесты: 2
10.01.2016, 22:46  [ТС] 10
Ой, гоню, не с той стороны приплюсовал...

bDataOut + i * 16 + 16
Ну тут же по 16 байт копируется.
С первой итерации i == 0.

Т.е.
0 * 16 = 0
1 * 16 = 16

А у меня будет:
0 * 16 + 16 = 16
1 * 16 + 16 = 32

Добавлено через 25 минут
Ещё 1 вопрос, как создать переменную в 16 байт?
Или может просто скопировать длину сразу в буффер?

1й зашифрованный блок у меня должен содержать длину всех данных(чтобы не потерять, а вернее не получить лишние байты при дешифровке).

eLen[0] - это длина текста в поле ввода:
C++
1
2
unsigned eLen[4];
eLen[0] = GetWindowTextLengthW(hEdit[1]); // Текст
Вот тут я длину всего текста засовываю в буфер:
C++
1
2
3
unsigned long long llDataLenght = eLen[0];      // Длина всего текста
 
for(int i = 0; i < 8; ++i) bDataBlocks[i] = llDataLenght >> (i * 8); // Записать длину текста в буфер побайтово
Но unsigned long long состоит всего из 8 байт, нет у меня конечно присвоено 0 по умолчанию в буфере:
C++
1
BYTE bDataBlocks[crypto.block_size] = {0};      // Буфер для шифрования, 16 ячеек
Но хотелось подстраховаться...

Или вот так может можно?:
C++
1
2
memcpy(bDataBlocks, eLen[0], sizeof(unsigned));         // Копировать длину данных в буфер
memset(bDataBlocks + sizeof(unsigned), 0, sizeof(BYTE) * (16 - sizeof(unsigned)));      // Добить буфер нулями
0
nonedark2008
1051 / 785 / 220
Регистрация: 28.07.2012
Сообщений: 2,187
10.01.2016, 22:58 11
Цитата Сообщение от артист Посмотреть сообщение
Или вот так может можно?:
memcpy(bDataBlocks, eLen[0], sizeof(unsigned));
Только
C++
1
memcpy(bDataBlocks, &eLen[0], sizeof(unsigned));
Добавлено через 2 минуты
memcpy копирует блок памяти, на который указывает второй указатель, в блок, на который указывает первый.
1
артист
94 / 20 / 20
Регистрация: 17.09.2014
Сообщений: 1,186
Завершенные тесты: 2
10.01.2016, 23:11  [ТС] 12
Спасибо ))
У меня на циклах вообще половину не выводило оказывается
0
10.01.2016, 23:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.01.2016, 23:11

Скопировать массив а в начало массива b
Помогите доделать программу, пожалуйста. Нужно скопировать массив а в начало...

В массив A скопировать неповторяющиеся элементы массива B
Сформулировать массив В из 30 элементов случайным образом. Вывести его.Из...

Массив: Как скопировать двумерный массив в другой массив?
Как скопировать двумерный массив в другой массив?


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru