PDA

Просмотр полной версии : Delphi 2010 и функции HexToString/StringToHex


Asmoday
04.11.2010, 09:21
Доброго времени суток всем! Вобщем-то вопрос по большей части наверно адресован xkor'у. Вобщем в связи с некоторыми недоработками в D2007 был вынужден перепрыгнуть на D2010. В следствие чего возникла небольшая проблемка, функциии преобразования работают не корректно. После преобразования данных из хекса в строку и отправки вместо:

4A000000000A000000000014043E04310440043E0420003F04 3E04360430043B043E043204300442044C0420003D04300420 003D0430044804200041043504400432043504400421000000


получаю:

4A0000000000000000000A000000000000000000000014003E 00310040003E0020003F003E00360030003B003E0032003000 42004C0020003D00300020003D003000480020004100350040


Функции:

function StringToHex(str1,Separator:String):String;
var
i:Integer;
begin
Result:='';
for i:=1 to Length(str1) do begin
Result:=Result+IntToHex(Byte(str1[i]),2)+Separator;
end;
end;

function SymbolEntersCount(s: string): string;
var
i: integer;
begin
Result := '';
for i := 1 to Length(s) do
if not CharInSet(s[i],[' ',#10,#13]) then
Result:=Result+s[i];
end;

function HexToString(Hex:String):String;
var
bt:Byte;
i:Integer;
begin
Result:='';
Hex:=SymbolEntersCount(UpperCase(Hex));
for i:=0 to (Length(Hex) div 2)-1 do begin
bt:=0;
if (Byte(hex[i*2+1])>$2F)and(Byte(hex[i*2+1])<$3A)then
bt:=Byte(hex[i*2+1])-$30;
if (Byte(hex[i*2+1])>$40)and(Byte(hex[i*2+1])<$47)then
bt:=Byte(hex[i*2+1])-$37;
if (Byte(hex[i*2+2])>$2F)and(Byte(hex[i*2+2])<$3A)then
bt:=bt*16+Byte(hex[i*2+2])-$30;
if (Byte(hex[i*2+2])>$40)and(Byte(hex[i*2+2])<$47)then
bt:=bt*16+Byte(hex[i*2+2])-$37;
Result:=Result+char(bt);
end;
end;


Я не могу понять по какому алгоритму идет преобразование, потому собственно и не могу поправить самостоятельно. Думаю связано это с тем что D2010 внесено много изменений касающихся строк. Хотелось бы услышать пояснение к коду.
ЗЫ: Сори за нубство =)

Вопрос снят. Порывшись нарыл вот это:

В Delphi 2009 строковым типом по умолчанию является новый тип UnicodeString. По умолчанию UnicodeString схож с кодировкой UTF-16, той же самой, что используется в Windows. Это отличие от предыдущей версии, в которой по умолчанию использовался тип AnsiString. Раньше в Delphi RTL для обработки данных в формате Юникод использовался тип WideString, но этот тип, в отличие от AnsiString, не подсчитывал количество ссылок (not reference-counted) и поэтому не мог рассматриваться Delphi-разработчиками как строковый тип по умолчанию.

Для Delphi 2009 новый тип UnicodeString был разработан таким образом, чтобы сочетать в себе достоинства и AnsiString, и WideString. UnicodeString может содержать как Юникод-символы, так и однобайтные ANSI символы. (Имейте ввиду, что Вы по-прежнему можете использовать AnsiString и WideString). Типы Char и PChar теперь олицетворяют соответственно WideChar и PWideChar. Учтите, что ни один тип строк не исчез, все типы, которыми пользовались разработчики, по-прежнему существуют и работают точно так же, как и раньше.

Итак, в Delphi 2009 обычная строка (string) будет эквивалентна UnicodeString, обычный символ (Char) – это теперь WideChar, а указатель на него (PChar) – это PWideChar.

Таким образом просто указывал типы строк не String, а AnsiString.

Для тех кому интересно почитать полный текст статей:
http://edn.embarcadero.com/article/38446
http://edn.embarcadero.com/article/38582
http://edn.embarcadero.com/article/38703

xkor
04.11.2010, 15:30
Asmoday, вот ещё в качестве бонуса более быстрый и стабильный вариант StringToHex:
function StringToHex(str1: AnsiString; sep: AnsiChar = #0): AnsiString;
const
hexAlf: array[0..15] of AnsiChar = '0123456789ABCDEF';
var
i,size:Integer;
begin
size:=Length(str1);
if sep=#0 then begin
SetLength(Result,size*2);
for i:=1 to size do begin
Result[i*2-1]:=hexAlf[Byte(str1[i]) shr 4];
Result[i*2]:=hexAlf[Byte(str1[i]) and $f];
end;
end else begin
SetLength(Result,size*3);
for i:=1 to size do begin
Result[i*3-2]:=hexAlf[Byte(str1[i]) shr 4];
Result[i*3-1]:=hexAlf[Byte(str1[i]) and $f];
Result[i*3]:=sep;
end;
end;
end;

Asmoday
30.01.2011, 05:07
xkor, тут еще вопросик к тебе, попытался перекомпилить inject.dll в 2010, но ничего не получилось. После долгих раздумий пришел к выводу, что проблема заключается в advAPIHook.pas. Нет ли готового решения? Не хочется перелопачивать несколько десятков функции.

xkor
31.01.2011, 01:57
Asmoday, боюсь не использовал пока этот модуль на 2009+ дельфе...