| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Самый быстрый алгоритм Base64? |
| Автор: Ak47black 31.3.2007, 12:51 |
| Кодирую и декодирую , очень большие потоки данных при помоши Base64 и хотелбы узнать самый быстрый алгоритм. Может кто поделиться, буду очень благодарин. Видал много вариантов ,включая с DRKB3, хотелбы найти найбыстрейший способ. |
| Автор: W4FhLF 31.3.2007, 14:55 |
| Ну могу дать тебе пример на ассемблере, работает очень быстро, но переписать придётся тебе PS Кинь сюда протестированные тобой варианты и их результаты, а так же условия тестирования. Может табличку какую составим. |
| Автор: Ak47black 31.3.2007, 15:04 | ||
| W4FhLF, я толком тестить неумею, но так как у меня большими кусками шифрует то разница сразу видна. Пока-что на этом остановился
|
| Автор: W4FhLF 31.3.2007, 16:04 | ||
| Жесть Пробуй:
|
| Автор: Ak47black 31.3.2007, 16:14 |
| А в обратную сторону? |
| Автор: W4FhLF 31.3.2007, 16:29 | ||
Как скорость? |
| Автор: Ak47black 31.3.2007, 16:34 |
| Шас заценю. Добавлено через 7 минут и 24 секунды А как-бы тут мне сделать что-бы string функция принималаю и возврашала?, а то неудобно |
| Автор: Ak47black 31.3.2007, 17:45 |
| W4FhLF, твои функции быстрые но тут одна пролема ,как подсшитать длину выходной строки? |
| Автор: W4FhLF 31.3.2007, 18:00 |
| Ak47black, точно так же, как и обычной: lenght(s2) |
| Автор: Ak47black 31.3.2007, 18:02 |
| W4FhLF, Да точно, сорри я тут уже запутался. Спасибо за код. + |
| Автор: Alix 28.12.2009, 19:39 | ||
Видел функцию для подсчета необходимой длины ДО декодирования, чтобы создать буфер необходимой длины:
Взято сhttp://www.delphi3000.com/articles/article_3404.asp?SK=, там тоже на ассемблере, кстати. Пишу для тех, кто наткнется на тему по поиску. |
| Автор: Alix 28.12.2009, 20:16 | ||
| Кстати, код из http://forum.vingrad.ru/index.php?showtopic=143825&view=findpost&p=1082228 не переваривает во входной строке символы с 0 кодом. Взял код для конвертации по ссылке из своего предыдущего поста. Получилось примерно так (это только implementation часть модуля):
|
| Автор: CodeMonkey 29.12.2009, 15:01 | ||
| Код по ссылке http://www.delphi3000.com/articles/article_3404.asp?SK= , а также код от Alix содержит баг. Конкретно - memory corruption. Ещё конкретнее: в Base64Encode, третья строка (mov EAX, EBX) - какой ещё EBX? Он неопределён. Добавлено @ 15:04 Поправленный and оптимизированный вариант (прошёл тесты и работает, кстати, быстрее ассемблерного варианта от Delphi3000):
|
| Автор: Alexeis 29.12.2009, 15:17 | ||
Разве параметры функции не передаются в регистрах? |
| Автор: Rrader 29.12.2009, 17:38 |
| В таком порядке - eax, edx, ecx, stack |
| Автор: Alexeis 29.12.2009, 19:59 |
| Обратите внимание на procedure Base64Encode(const InBuffer; InSize: Cardinal; var OutBuffer); overload; register; Возможно эта директива что-то меняет в передаче параметров (хотя это больше похоже на порт с паскаля) |
| Автор: Rrader 29.12.2009, 20:09 |
| Директива register есть соглашение: Register в Delphi подразумевается по умолчанию, поэтому мы даже не пишем ее. Это __fastcall. |
| Автор: Alexeis 29.12.2009, 20:51 |
| // load InSize (stored in EBX) Судя по комменту следует EBX заменить на EDX |
| Автор: CodeMonkey 29.12.2009, 22:05 |
А так и работает... затирая вам память... А ещё лучше - на InSize, как это сделано (правильно, кстати) в Base64Decode. Добавлено @ 22:08 P.S. Столкнулся с этим в поддержке EurekaLog. Мы получили баг-отчёт с memory corruption на ровном месте. К счастью была предоставлена воспроизводимая демка, и я по ней вышел на этот код, который когда-то был взят с Delphi3000 и встроен в EurekaLog. Вместе с багом. Удивительно, что это работало несколько лет. Окей, наверняка кто-то сталкивался с загадочными багами, но причину найти не могли. Вот она, сила copy&paste. Добавлено @ 22:14 P.P.S. Конкретно в варианте с EurekaLog EBX оказывался равен OutSize из Base64EncodeStr (вместо InSize; InSize <= OutSize). Соответственно, Base64Encode кодировала больше данных, чем было нужно (заодно портя память, т.к. выходной буфер был предназначен только для содержания кодированных InSize байт, а не OutSize байт). Например, вместо взятия, скажем, 11-ти байт с входного буфера и записи их в 16-ти байтный выходной буфер, эта функция брала 16 байт из исходного буфера (ага, шанс на AV не сработал) и записывала 24 байта в выходной буфер (который имел размер 16 байт). Добавлено через 14 минут и 1 секунду Кстати, сишный fastcall не совместим с register: он использует только два регистра (ECX и EDX) вместо трёх и имеет другую семантику. |
| Автор: Alexeis 29.12.2009, 22:32 | ||
Ну тогда бы билдер не смог компилироваться с делфи. Везде где делфийские вызовы у него __fastcall, так что либо билдер обманывает либо MS __fastcall отличается от билдеровского. |
| Автор: CodeMonkey 29.12.2009, 22:35 |
Могу ошибаться, но в 16-ти битном Паскале вроде бы не было соглашения register. Возможно, это был порт с Delphi 1. Хз. Добавлено через 1 минуту и 16 секунд Вы меня неверно поняли. Я не говорил про билдеровский __fastcall. Я говорил про MS-ский fastcall. Это разные вещи. Про что я и сказал. |
| Автор: Rrader 1.1.2010, 17:04 | ||
Здесь имелось в виду, что __fastcall в Delphi - это register (свое зарезервированное слово), по аналогии с другими компиляторами, где __fastcall прописывается как есть. Соглашение о вызове так и называется - fastcall. Причем у __fastcall есть несколько вариантов (мне известно 4). Наверное, мне стоило убрать два нижних подчеркивания, потому что к Delphi они здесь особого отношения не имеют, зато вводят в заблуждение |