Форум: "Прочее";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2011.10.16;
Скачать: [xml.tar.bz2];




Вниз

MD5 и WideString 


DVM ©   (2011-06-21 14:54) [0]

Как вы думаете, как правильно вычислять MD5 от WideString:

a) Предварительно преобразовав ее к AnsiString с учетом текущей локали (WideCharToMultiByte), а потом вычислять MD5 от буфера, содержащего полученный AnsiString?
б) Вычислять MD5 сразу от буфера, содержащего WideString?



RWolf ©   (2011-06-21 15:04) [1]

в случае а) программа в системе с английской локалью неправильно будет обрабатывать данные, подготовленные программой в системе с русской локалью.



Медвежонок Пятачок ©   (2011-06-21 15:25) [2]

правильнее наверное как от куска бинарника.
с другой стороны если это для поиска(хеш-таблиц) то наверное как от строки



Омлет ©   (2011-06-21 15:33) [3]

Смотря где оно потом используется.. Если на сервер отсылается, к примеру, надо делать, чтобы было совместимо.



DVM ©   (2011-06-21 15:44) [4]


> Смотря где оно потом используется..

Да это понятно. Мне казалось, что должны быть какие то правила. Но похоже их нет.

Пока остановился на варианте a), причем для старых версий делфи использую
WideCharToMultiByte для приведения строки к Ansi, в новых версиях TEncoding.GetBytes, во FreePascal Utf8ToAnsi.

Для варианта б) результаты от одного и того же по содержанию текста получаются различные. А это имхо неправильно.



RWolf ©   (2011-06-21 15:57) [5]


> Для варианта б) результаты от одного и того же по содержанию
> текста получаются различные.

это как?



DVM ©   (2011-06-21 16:06) [6]


> RWolf ©   (21.06.11 15:57) [5]

Я не верно выразился.

Я хотел сказать, что если для исходной WideString строки, содержащей слово, скажем "Привет" вычислять MD5 как от массива байт, то он разумеется будет отличаться от MD5 полученного от того же слова, содержащегося в строке AnsiString. Аналогично для UTF8, UnicodeString и всего прочего зоопарка кодировок. Но слово то одно и то же! Имхо результат MD5 должен выходить одним и тем же.



tesseract ©   (2011-06-21 16:35) [7]


> Но слово то одно и то же!


А сообщение-то разное.



Anatoly Podgoretsky ©   (2011-06-21 16:47) [8]

> DVM  (21.06.2011 16:06:06)  [6]

Ну тогда и строки надо приводить к одному и тоже. Лучше к Юникод



Pavia ©   (2011-06-21 16:53) [9]

Есть такое правило. Вернее модель. Все вычисления должны быть единообразны и выполняться они должны во внутренним формате который наиболее удобной для вас. А вот преобразовывать надо только при вводе и выводе.



DVM ©   (2011-06-21 16:58) [10]


> Pavia ©   (21.06.11 16:53) [9]


> Anatoly Podgoretsky ©   (21.06.11 16:47) [8]

Вы правы. Я собственно пришел к тому же выводу после некоторых раздумий.
MD5 он по идее знать не знает ни о каких кодировках, а работает с байтами.



Дмитрий С ©   (2011-06-21 17:13) [11]

Нужно указывать кодировку, думаю. Я бы utf8 использовал как наиболее популярную для юникода.



DVM ©   (2011-06-21 17:30) [12]


> Дмитрий С ©   (21.06.11 17:13) [11]

так я и сделал:


 TMD5 = class(TObject)
 public
   {$IFDEF UNICODE}
   class function Calculate(const X: TBytes): TMD5Digest; overload;
   class function Calculate(const S: RawByteString): TMD5Digest; overload;
   class function Calculate(const S: UnicodeString; const Encoding: TEncoding): TMD5Digest; overload;
   class function Calculate(const S: UnicodeString): TMD5Digest; overload;
   {$ELSE}
   class function Calculate(const S: string): TMD5Digest; overload;
   {$ENDIF}
   class function Calculate(const Stream: TStream): TMD5Digest; overload;
   class function Calculate(const Buffer; Size: Integer): TMD5Digest; overload;
   class function CalculateFile(const FileName: string): TMD5Digest;
   class function DigestToStr(const Digest: TMD5Digest): string;
   class function StrToDigest(const S: string): TMD5Digest;
   class function DigestCompare(const Digest1, Digest2: TMD5Digest): Boolean;
 end;


Для старых версий Delphi и FPC (у которого строки как оказалось UTF8) класса TEncoding нет, поэтому для них используется вариант по-умолчанию, без указания кодировки, к нужной кодировке строку приводит тот кто использует класс.



Дмитрий С ©   (2011-06-22 06:42) [13]


>  FPC (у которого строки как оказалось UTF8)

У фрипаскаля строки UTF8?
т.е.
var S: String;
S := "Привет"; <- в UTF8 будет храниться?



DVM ©   (2011-06-22 07:27) [14]


> Дмитрий С ©   (22.06.11 06:42) [13]


> S := "Привет"; <- в UTF8 будет храниться?

да и Length для нее возвращает 12, а для  "Привет123" - 15.



Дмитрий С ©   (2011-06-22 17:18) [15]


> DVM ©   (22.06.11 07:27) [14]
>
>

А к примеру S[2]  чему будет равно? явно не "р" - так же не удобно.



DVM ©   (2011-06-22 18:24) [16]


> Дмитрий С ©   (22.06.11 17:18) [15]


> явно не "р" - так же не удобно.

почему неудобно? "р" и будет. А Length в байтах я так понял во FreePascal возвращает размер. Или даже не в байтах, а в каких то единицах (кодовых точках что ли), забыл я их правильное название, в документе по переходу на Unicode для Delphi 2009 рассказывается об этом.



Дмитрий С ©   (2011-06-23 06:58) [17]


> DVM ©   (22.06.11 18:24) [16]

Так если Length("Привет123")  - 15 то уже нельзя будет делать for i=1 to length(s) do s[i]... Всяко сначала придется в widestring переводить. Да и странно, обычно utf8 используется для передачи и постоянного хранения строк, а не для использования такого.




Форум: "Прочее";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2011.10.16;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.75 MB
Время: 0.019 c
2-1309050691      Drowsy                2011-06-26 05:11  2011.10.16  
Перехват исключения при создании формы.


2-1309024072      eXAAAXe               2011-06-25 21:47  2011.10.16  
Максимальное разрешение экрана.


15-1308757875     Сергей М.             2011-06-22 19:51  2011.10.16  
MegaPixel (с) MegaCar сервер


2-1307957801      Jamix                 2011-06-13 13:36  2011.10.16  
KDTele Tools


8-1205914978      Franzy                2008-03-19 11:22  2011.10.16  
OpenGL - как сделать "скриншот"?