Russian Qt Forum
Ноябрь 26, 2024, 13:50 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Как поместить в int 8-битный код русского символа?  (Прочитано 13811 раз)
Alexu007
Гость
« Ответ #15 : Март 13, 2014, 21:36 »

Шифрование побайтовое примитивное, но задачи и не ставится зашифровать абсолютно. Достаточно, что из осмысленного файла будет мешанина байт -  это я уже реализовал.  По поводу записи/чтения - если по байту, не стоит вопроса конца файла - читаем до !EOF. Если читать блоками - последний блок наверняка будет заполнен не полностью (файл не будет кратен), нужно это программно отслеживать, особенно при записи. Ну, сами понимаете. Это может быстрее, но требует дополнительных телодвижений програмиста.

Основное требование: дешифрованный файл 100% должен соответствовать исходному.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #16 : Март 13, 2014, 21:39 »

Это может быстрее, но требует дополнительных телодвижений програмиста.
Да нет там никаких дополнительных телодвижений.
Простите, но это какие то детские причины. Подмигивающий

От проседания производительности вас спасает fread/fwrite, которые буферезированы под капотом. Улыбающийся
« Последнее редактирование: Март 13, 2014, 21:48 от Old » Записан
OKTA
Гость
« Ответ #17 : Март 13, 2014, 23:30 »

Если размер последнего блока не совпадает с размером стандартного блока, с которым работает шифр, то используют паддинг, например очень простой и понятный -
http://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7
Old прав. На маленьких файлах разницы не заметишь в побайтовом-поблочном чтении, но чем больше файл и чем больше их количество, тем заметнее будет разница.
Записан
Alexu007
Гость
« Ответ #18 : Март 14, 2014, 07:21 »

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

Код
C++ (Qt)
   // цикл шифрования
   while(1)
      {
      fread (&read_byte, sizeof(char), 1, inpf);
      if (feof(inpf)) break;
 
      write_byte = fn_Shifr_byte(read_byte);
 
      fwrite (&write_byte, sizeof(char), 1, outf);
      }


Допустим я начну читаю его блоками по 1024 байта. Последний блок почти всегда будет заполнен не полностью - нужно это отслеживать. И при записи последний блок нужно добавлять не полностью.

Конечно на самом деле ничего не читается "по байту". Чтение/запись неявно буферизуется либо самой программой, либо виндой. Вот и интересно, чтение блоками даст выигрыш в скорости?
Записан
OKTA
Гость
« Ответ #19 : Март 14, 2014, 07:32 »

Optimum buffer size is related to a number of things: file system block size, CPU cache size and cache latency.

Most file systems are configured to use block sizes of 4096 or 8192. In theory, if you configure your buffer size so you are reading a few bytes more than the disk block, the operations with the file system can be extremely inefficient (i.e. if you configured your buffer to read 4100 bytes at a time, each read would require 2 block reads by the file system). If the blocks are already in cache, then you wind up paying the price of RAM -> L3/L2 cache latency. If you are unlucky and the blocks are not in cache yet, the you pay the price of the disk->RAM latency as well.

This is why you see most buffers sized as a power of 2, and generally larger than (or equal to) the disk block size. This means that one of your stream reads could result in multiple disk block reads - but those reads will always use a full block - no wasted reads.

Now, this is offset quite a bit in a typical streaming scenario because the block that is read from disk is going to still be in memory when you hit the next read (we are doing sequential reads here, after all) - so you wind up paying the RAM -> L3/L2 cache latency price on the next read, but not the disk->RAM latency. In terms of order of magnitude, disk->RAM latency is so slow that it pretty much swamps any other latency you might be dealing with.

So, I suspect that if you ran a test with different cache sizes (haven't done this myself), you will probably find a big impact of cache size up to the size of the file system block. Above that, I suspect that things would level out pretty quickly.

There are a ton of conditions and exceptions here - the complexities of the system are actually quite staggering (just getting a handle on L3 -> L2 cache transfers is mind bogglingly complex, and it changes with every CPU type).

This leads to the 'real world' answer: If your app is like 99% out there, set the cache size to 8192 and move on (even better, choose encapsulation over performance and use BufferedInputStream to hide the details). If you are in the 1% of apps that are highly dependent on disk throughput, craft your implementation so you can swap out different disk interaction strategies, and provide the knobs and dials to allow your users to test and optimize (or come up with some self optimizing system).
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #20 : Март 14, 2014, 07:53 »

Ну как же?
Пишу код прямо здесь, поэтому могут быть опечатки. Улыбающийся
Код
C++ (Qt)
QFile in( ... );
QFile out( ... );
 
// Открываем файлы
 
while( !in.atEnd() )
{
   QByteArray src = in.read( 1024 );
   QByteArray dst = coded_buffer( src );
   out.write( dst );
}
 

Код
C++ (Qt)
QByteArray coded_buffer( const QByteArray &src )
{
   const int sz = src.size();
   QByteArray result( sz, 0 );
   for( int i = 0; i < sz; ++i )
   {
        // Кодируем
   }
 
   return result;
}
 

Конечно на самом деле ничего не читается "по байту".
Да, fread буферизирован сам по себе.
Но если бы вы использовали обычный read, то скорость упала бы значительно.
« Последнее редактирование: Март 14, 2014, 08:55 от Old » Записан
Alexu007
Гость
« Ответ #21 : Март 14, 2014, 13:47 »

Спасибо за помощь. Попробую и ваш вариант - насколько окажется быстрее.
« Последнее редактирование: Март 14, 2014, 13:49 от Alexu007 » Записан
Alexu007
Гость
« Ответ #22 : Март 16, 2014, 08:12 »

Ваш вариант быстрее минимум в 2 раза. В связи с чем возник следующий вопрос:

1. как втиснуть int в 4 байта, ну например в quint8 A[4] - так чтобы была возможна, например, побайтовая запись в файл? Напрямую же не получится присвоить?

2. как проще этот int вытащить обратно из байтов?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #23 : Март 16, 2014, 08:41 »

1. как втиснуть int в 4 байта, ну например в quint8 A[4] - так чтобы была возможна, например, побайтовая запись в файл? Напрямую же не получится присвоить?
2. как проще этот int вытащить обратно из байтов?
Вы хотите читать кусок файла в QByteArray, а потом разбирать его на инты?
Тогда лучше воспользоваться для этого QDataStream.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #24 : Март 16, 2014, 09:47 »

1. как втиснуть int в 4 байта, ну например в quint8 A[4] - так чтобы была возможна, например, побайтовая запись в файл? Напрямую же не получится присвоить?
Да чего ж не получится
Код
C++ (Qt)
union MyInt {
int i;
quint8 a[4];
};
 
MyInt test;
test.i = 44;
stream << test.a[0] << ...
 
Или даже так
Код
C++ (Qt)
int i = 5;
quint8 * dummy = (quint8 *) &i;   // или reinterpret
 

Не очень ясно чего Вы хотите добиться
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #25 : Март 16, 2014, 09:49 »

Да чего ж не получится
С byte order могут случиться неприятности. Файл на разных платформах могут попробовать открыть.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #26 : Март 16, 2014, 10:23 »

С byte order могут случиться неприятности. Файл на разных платформах могут попробовать открыть.
После перехода на Intel Mac (где-то в районе 2006) "большая индиана" как бы уже "дань истории", затрудняюсь привести пример такой платформы. Хотя по-прежнему считается хорошим тоном хранить данные на диске в big endian.

Возвращаясь к теме: не связывайтесь с fread/fwrite, будете латать долго и все равно будет плохо. Используйте QDataStream, а если нужно что-то с байтами, то выливайте напр в QByteArray и там уже резвитесь
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #27 : Март 16, 2014, 10:33 »

После перехода на Intel Mac (где-то в районе 2006) "большая индиана" как бы уже "дань истории", затрудняюсь привести пример такой платформы.
То что вы не знаете таких платформ, не означает что их нет. Пример ARM - они bi. Улыбающийся И хоть в большинстве своем их запускают в little, но big до сих пор очень возможен с увеличением популярности армов.

Хотя по-прежнему считается хорошим тоном хранить данные на диске в big endian.
Как это соотносится с вашими примерами с union? Или вы продемонстрировали, что знаете как работает union?
« Последнее редактирование: Март 16, 2014, 10:45 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #28 : Март 16, 2014, 12:04 »

Как это соотносится с вашими примерами с union? Или вы продемонстрировали, что знаете как работает union?
Не заводитесь, я просто ответил на вопрос  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #29 : Март 16, 2014, 12:12 »

Не заводитесь, я просто ответил на вопрос  Улыбающийся
Да, неправильно. Подмигивающий
Вот мне и стало интересно: для чего советовать одно, а самому делаете наоборот. Улыбающийся
Ну да ладно, это не вопрос. Улыбающийся
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.145 секунд. Запросов: 23.