Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.11.2011, 04:09   #1
myosotis
 
Регистрация: 15.11.2011
Сообщений: 9
Вопрос md5 в delphi: проблема с русскими буквами

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,IdHashMessageDigest, StdCtrls, Buttons;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    bbOK: TBitBtn;
    bbClean: TBitBtn;
    procedure bbCleanClick(Sender: TObject);
    procedure bbOKClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function md5(S: string): String;
begin
  Result := '';
  with TIdHashMessageDigest5.Create do
  try
    Result:=AnsiLowerCase(HashStringAsHex(s));
  finally
    Free;
  end;
end;

procedure TForm1.bbCleanClick(Sender: TObject);
begin
Edit1.Clear;
Edit2.Clear;
end;

procedure TForm1.bbOKClick(Sender: TObject);
begin
edit2.text:=md5(Edit1.Text)
end;

end.
Алгоритм md5 использовала через пакет Indy - класс TIdHashMessageDigest5
Функция правильно работает c числами и английскими буквами (проверено через онлайн генератор).
:
А вот с русскими буквами не хочет: для слов одинаковой длины выдает один и тот же хеш.
Почему так происходит и как это исправить?
myosotis вне форума Ответить с цитированием
Старый 16.11.2011, 08:24   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Delphi какой версии? >= Delphi 2009 ?

1) попробуйте конвертировать строку в AnsiString
или хотя бы задать тип, вместо String -> AnsiString:
Код:
function md5(S: AnsiString):AnsiString;
begin
  Result := '';
  with TIdHashMessageDigest5.Create do
  try
    Result:=AnsiLowerCase(HashStringAsHex(s));
  finally
    Free;
  end;
end;

....
procedure TForm1.bbOKClick(Sender: TObject);
var s : AnsiString;
begin
  s := Edit1.Text;
  edit2.text:=md5(s);
end;

2) в той теме, где Вы нашли этот способ получения хеша, были и другие библиотеки получения хэша MD5.
попробуйте их.
(но замечание насчёт использования AnsiString вместо String всё равно остаётся в силе!!)
Serge_Bliznykov вне форума Ответить с цитированием
Старый 16.11.2011, 15:12   #3
myosotis
 
Регистрация: 15.11.2011
Сообщений: 9
По умолчанию

у меня Delphi 2010. я вот и думаю, что все дело в версии. т.к некоторые программы, ранее созданные в Delphi 2007 и нормально работающие с русскими буквами, теперь не работают в Delphi 2010((
Замена String -> AnsiString мне ничего не дала
myosotis вне форума Ответить с цитированием
Старый 16.11.2011, 16:23   #4
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

В данном случае вы пали жертвой мего-мозга создателей инди. Ваша строчка должна выглядеть примерно так:

Код:
Result:=AnsiLowerCase(HashStringAsHex(s, TIdMBCSEncoding.Create()));
Это если с утечкой памяти. Чтобы утечек не было, храните TIdMBCSEncoding.Create() как глобальный объект.


Код:
function md5(S: AnsiString):AnsiString;
тут это не помогает, т.к. мего-мозг уже позаботился о нас Вот в этих самых строчках позаботился:

Код:
    // replace illegal characters > $7F
    if Word(AChars^) > $007F then begin
      ABytes^ := Byte(Ord('?'));
    end else begin
      ABytes^ := Byte(AChars^);
    end;
Я не знаю, что курят RLebeau и Ко, но, судя по последним релизам, что-то очень нездоровое
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось veniside; 16.11.2011 в 16:31.
veniside вне форума Ответить с цитированием
Старый 16.11.2011, 16:59   #5
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,551
По умолчанию

Юнит md5hash:
Вложения
Тип файла: zip md5hash.zip (1.7 Кб, 226 просмотров)
Arigato вне форума Ответить с цитированием
Старый 16.11.2011, 17:41   #6
psycho-coder
Участник клуба
 
Аватар для psycho-coder
 
Регистрация: 06.04.2009
Сообщений: 1,524
По умолчанию

Цитата:
(но замечание насчёт использования AnsiString вместо String всё равно остаётся в силе!!)
Как уже сказали выше, это не поможет. К тому же по умолчанию используется AnsiString, потому что String = Паскалевскому String[255].
psycho-coder вне форума Ответить с цитированием
Старый 16.11.2011, 17:45   #7
myosotis
 
Регистрация: 15.11.2011
Сообщений: 9
По умолчанию

Цитата:
TIdMBCSEncoding.Create()
это что? как описать это имя?
myosotis вне форума Ответить с цитированием
Старый 16.11.2011, 18:14   #8
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Цитата:
К тому же по умолчанию используется AnsiString
начиная с Дельфи 2009 string = UnicodeString;
Цитата:
потому что String = Паскалевскому String[255].
перепутали string и ShortString.
Цитата:
это что? как описать это имя?
Код:
var
  enc: TIdMBCSEncoding;
begin
  enc := TIdMBCSEncoding.Create(); // один раз при старте
...
  enc.Free(); // при выходе
end;
там, где в инди нужна кодировка:
Код:
Result:=AnsiLowerCase(HashStringAsHex(s, enc));
Но, следует учесть, что эти пляски с кодировкой могут дать не тот результат, который ожидается по стандарту. Нужно внимательно читать, что там стандарт говорит про хэш от не-ASII символов. Если стандарта нет, можно забить. (Речь не про стандарт MD5, а про ту часть, которая требует брать хэш от строки).
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось mihali4; 17.11.2011 в 00:14.
veniside вне форума Ответить с цитированием
Старый 16.11.2011, 18:35   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

сорри за оффтоп

Цитата:
Сообщение от psycho-coder
К тому же по умолчанию используется AnsiString, потому что String = Паскалевскому String[255].
абсолютно неверное утверждение.
ибо
1) в Delphi это всегда задавалось параметром {$H+}
по умолчанию String == AnsiString
можно было включить {$H-}. Тогда String станет равным ShortString

2) в версиях Delphi c unicode (версия >=2009) String по умолчанию равен WideString (UnicodeString).
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
SHA1-хеширование (проблемы с русскими буквами) BDA Общие вопросы Delphi 7 15.09.2017 09:15
Паскаль. Файлы - Создать подпрограмму для заполнения файла латинскими и русскими буквами Антон Лысенко Помощь студентам 2 15.12.2010 22:44
Дан файл, содержащий текст, записанный строчными русскими буквами. Получить в др.файле тот же текст, develish151 Microsoft Office Word 4 05.05.2010 13:20
Пути с русскими буквами в Lazarus. Alex Cones Lazarus, Free Pascal, CodeTyphon 4 30.03.2010 18:31
SMS русскими буквами nimf Общие вопросы Delphi 10 13.02.2010 22:23