Как быстро декодировать (сдвигать и ксоринг) массив байтов? - PullRequest
1 голос
/ 08 декабря 2010

Как быстро декодировать (сдвигать и сохранять) массив массива байтов?Мне это нужно для приложения просмотра файлов, которое открывает файл архива и декодирует файлы внутри и отображает их пользователю.Файлы зашифрованы с помощью системы сдвига байтов и ксоринга.Мне невозможно изменить алгоритм.В настоящее время я просто читаю все байты и затем запускаю на них функцию декодирования.

Используемая в настоящее время функция декодирования:

    byte[] DecodeVOQ(byte[] EncodedBytes)
    {
        for (int i = 0; i < EncodedBytes.Length; i++)
        {
            EncodedBytes[i] ^= (byte)194;
            EncodedBytes[i] = (byte)((EncodedBytes[i] << 4) | (EncodedBytes[i] >> 4));
        }
        return EncodedBytes;
    }

Редактирование: Я нашелВыяснилось, что реальная проблема производительности заключается в отображении текста.Чтение + декодирование довольно быстрое.

Ответы [ 6 ]

7 голосов
/ 08 декабря 2010

Одна возможная оптимизация будет заключаться в предварительном вычислении вывода для любого входного байта.Таким образом, вы получите:

private static byte[] DecodedBytes = PrecomputeDecodedBytes();

public static byte[] DecodeVOQ(byte[] data)
{
    for (int i = 0; i < data.Length; i++)
    {
        data[i] = DecodedBytes[data[i]];
    }
    return data;
}

Вполне возможно, что это будет медленнее, чем ваш существующий алгоритм сдвига битов.РЕДАКТИРОВАТЬ: Я только что попытался сравнить это с исходным битовым сдвигом, но с использованием временной локальной переменной: они примерно одинаковы.

Вы тестировали текущую производительность?Это определенно слишком медленно?В частности, загрузка файла практически с любого носителя данных будет намного намного медленнее, чем стоимость декодирования.Я только что попробовал это на своем ноутбуке - для 200 МБ данных это занимает около полсекунды.(РЕДАКТИРОВАТЬ: С ответом Марсело, это займет при полсекунды.) Это действительно слишком медленно?

Будете ли вы рады использовать более одного процессора?В конце концов, это смущающая распараллеливаемая рутина.Если вы используете .NET 4, TPL вполне может сделать это довольно простым.

Я должен еще раз подчеркнуть, что это не «шифрование» - это мягкая форма запутывания, так же, как кодировка base-64 имени пользователя / пароля для базовой HTTP-аутентификации.

2 голосов
/ 08 декабря 2010

Вы можете ускорить процесс с помощью временного:

    byte b = EncodedBytes[i] ^ (byte)194;
    EncodedBytes[i] = (byte)((b << 4) | (b >> 4));

Вы можете еще больше ускорить процесс, используя unsafe и необработанные указатели, таким образом избегая проверенных обращений (хотя я не знаю, учитывается ли это с текущими оптимизаторами JIT).

2 голосов
/ 08 декабря 2010

Я думаю, что табличный подход будет быстрее, верно? Так как это всего лишь байты, и ни один байт не зависит от соседнего байта, есть только 256 возможных вариантов, поэтому просто ищите каждый

0 голосов
/ 08 декабря 2010

Это не xor, это shift и or ...

В сборке это будет одна инструкция "повернуть байт на 4".

BTW не можетВы расшифровываете это по требованию?Декодируйте файл в блоках во время потоковой передачи файла.

0 голосов
/ 08 декабря 2010

Без .NET вы сможете декодировать эти 4 байта за раз, но здесь, на самом деле, единственное, что вы можете сделать, - это предварительно вычислить таблицу перевода.

0 голосов
/ 08 декабря 2010

Один из подходов, который следует учитывать, - это декодировать данные так, как они отображаются.То есть, декодировать только часть за раз.Но я подозреваю, что вы просто сбрасываете данные в элемент управления для редактирования или что-то в этом роде, что на самом деле не сделало бы эту возможность.Как вы отображаете данные?

Кроме этого, я не уверен, как бы вы слишком ускорили его.

...