Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.09.03;
Скачать: [xml.tar.bz2];

Вниз

HexToStr   Найти похожие ветки 

 
kiwooo   (2006-08-15 13:16) [0]

Привет! Искал в инетрнете способы перевода Hex - значения в Str элемент. Т.е. например
Hex := "757475";
HStr := HexToStr(Hex);


Итог  HStr = "utu"

Решение проблемы-то я нашел, но интересует, как быстрее и лучше сделать эту операцию (HexToStr).


 
Джо ©   (2006-08-15 13:19) [1]

> HexToStr

Что это за функция такая, HexToStr?


 
Джо ©   (2006-08-15 13:19) [2]

И что она должна делать-то?


 
Германн ©   (2006-08-15 13:24) [3]


HStr:="";
for i:=0 to (Length(Hex) div 2) - 1 do
 HStr:=HStr+Chr(Byte(StrToInt("$"+Copy(Hex(i*2+1,2)))));


 
begin...end ©   (2006-08-15 14:04) [4]

Если версия Delphi позволяет, используйте HexToBin.


 
Anatoly Podgoretsky ©   (2006-08-15 16:42) [5]

hex и так уже строка.


 
tesseract ©   (2006-08-15 16:46) [6]

uses SysUtils

hex:=$7575
Hstr:=IntToHex(hex,4);


 
Пусик ©   (2006-08-15 20:35) [7]

> tesseract ©   (15.08.06 16:46) [6]

hex:=$7575
Hstr:=IntToHex(hex,4);


Это к чему? Совсем далеко от ответа.

>kiwooo   (15.08.06 13:16)

Вот простенький пример:

function HexToStr(s:pchar):string;
begin
   SetLength(Result,StrLen(s)div 2);
   SetLength(Result,HexToBin(s, @result[1],StrLen(s)div 2));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Hex,Hstr:string;
begin
Hex := "757475";
HStr := HexToStr(pchar(Hex));
Label1.Caption:=HStr;
end;


 
Kolan ©   (2006-08-15 20:44) [8]


> Пусик ©   (15.08.06 20:35) [7]

Ну и что это делает?

Врный ответ:
Anatoly Podgoretsky ©   (15.08.06 16:42) [5]


 
Пусик ©   (2006-08-15 20:48) [9]


> Kolan ©   (15.08.06 20:44) [8]
> > Пусик ©   (15.08.06 20:35) [7]Ну и что это делает?


А теперь внимательно прочитай вопрос. Можешь несколько раз.


 
Пусик ©   (2006-08-15 20:50) [10]

>Kolan ©   (15.08.06 20:44) [8]

ps. [5] - ответ неверный.


 
Kolan ©   (2006-08-15 21:01) [11]


> Пусик ©   (15.08.06 20:50) [10]

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


> kiwooo   (15.08.06 13:16)

1. Нех - это и так строка.
2. А вом нужно Нех значение (например 75) превратить в число см. HexToBin
3. А затем полученое число преобразовать в символ см. Chr()


 
Kolan ©   (2006-08-15 21:03) [12]


> SetLength(Result,StrLen(s)div 2);

А если я буду писать 075?

С таким же успехом можно было предложить вариант:
function HexToStr: string;
begin
 Result := "utu"
end;

:)


 
Пусик ©   (2006-08-15 21:07) [13]


> А если я буду писать 075?


Обрати внимание, что 075 - не текстовый тип


 
Kolan ©   (2006-08-15 21:15) [14]

"075" это текстовый :)


 
Пусик ©   (2006-08-15 21:21) [15]


> Kolan ©   (15.08.06 21:15) [14]
> "075" это текстовый :)


И?
1. Правильность входных данных на совести автора.
2. Я знаю, что Земля не круглая, а Черное море не черное. И что?


> Kolan ©   (15.08.06 21:01) [11]
> > Пусик ©   (15.08.06 20:50) [10]Неплохо бы человеку обяснить,
>  что он неверно задал вопрос..> kiwooo   (15.08.06 13:16)
1. Нех - это и так строка.
2. А вом нужно Нех значение (например 75) превратить в число см. HexToBin
3. А затем полученое число преобразовать в символ см. Chr()


1. Так точно. Только зачем это повторять?
2. Код из [7] делает это без преобразования.
3. См. п. 2.


 
Kolan ©   (2006-08-15 21:26) [16]


> 2. Код из [7] делает это без преобразования.

Он то делает, но вводит в заблуждение автора. И оставит его думать, что нех и строка разные вещи, а это одно и тоже;

К томуже понимание того как это ракботает позволит дать ф-ции понятное название, а не бредовое HexToStr...


 
Пусик ©   (2006-08-15 21:34) [17]


> Kolan ©   (15.08.06 21:26) [16]
> > 2. Код из [7] делает это без преобразования.Он то делает,
>  но вводит в заблуждение автора. И оставит его думать, что
> нех и строка разные вещи, а это одно и тоже;


Автор прекрасно понимает это.
Еще раз внимательно перечитай вопрос. И не надо предлагать:
1. неэффективных методов(подобных [3] и [11]) как единственно верных;
2. неверных, подобно [5];
3. откровенно бредовых, как в [6].


 
Kolan ©   (2006-08-15 21:40) [18]

Пффф, то есть по вашему Hex - это не строка(в Delphi)? Так?

function IntToHex(Value: Integer; Digits: Integer): string; overload;

...


 
Virgo_Style ©   (2006-08-15 21:43) [19]

Такое чувство, что надо что-то вроде
IntToStr( StrToInt("$"+SomeHexString) );

Пусик ©   (15.08.06 21:34) [17]
[5] абсолютно верен в контексте [0]


 
Kolan ©   (2006-08-15 21:47) [20]


> Kolan ©   (15.08.06 21:40) [18]

Кстати заметте, что в IntToHex учитывается, что строка содержащая Нех может трактоватьзя по разному: Digits: Integer


 
tesseract ©   (2006-08-15 21:58) [21]

> [17] Пусик ©   (15.08.06 21:34)


Пусик решил опять всех покозлить. Опять убеждаюсь в правоте той статьи.

Только попробуй доказать что $7575 Delphi не воспримет как шестнадцетиричное значение.

> IntToStr( StrToInt("$"+SomeHexString) );


Я так и делаю, если значение строковое.  


> Пффф, то есть по вашему Hex - это не строка(в Delphi)? Так?


HEX не строка - а целое число, так мне доходчиво доказал преподователь по теории чисел в 1998 году.

При работе, например, с оборудованием оч полезно inttohex.


 
Anatoly Podgoretsky ©   (2006-08-15 21:59) [22]

За это время автор ни разу голос не подал.


 
Шпиён   (2006-08-15 22:15) [23]

> HEX не строка - а целое число,

У автора вопроса переменная  Hex - именно строка.
см. [0]

> Hex := "757475";
> HStr := HexToStr(Hex);
>
> Итог  HStr = "utu"


Как с помощью
> tesseract ©   (15.08.06 16:46) [6]
> uses SysUtils
>
> hex:=$7575
> Hstr:=IntToHex(hex,4);

получается ожидаемый результат "utu" ?


 
tesseract ©   (2006-08-15 22:40) [24]

> [23] Шпиён   (15.08.06 22:15)


перегруз у меня :-)

тогда присоединяюсь к [2].


 
Kolan ©   (2006-08-15 22:59) [25]


> доказал преподователь по теории чисел в 1998 году

Ну вообщем Hex - система счисления.

Я имел в виду что в Delphi нет формата для таких чисел(вроде Double, Intger) а используется string.. Мож я и не прав, но впрос что должна делать HexToStr у меня вознит сразу...


 
Шпиён   (2006-08-15 23:04) [26]


> тогда присоединяюсь к [2].

По моему, из [0] четко видно, что должна делать функция HexToStr -)
Присоединяюсь к [3], [4] и [7]
[3] - если версия Delphi не позволяет. Хотя для достаточно длинной строки я бы использовал код HexToBin из более свежих версий Delphi.
Delphi 6:

function HexToBin(Text, Buffer: PChar; BufSize: Integer): Integer; assembler;
const
 Convert: array["0".."f"] of SmallInt =
   ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
    -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
    -1,10,11,12,13,14,15);
var
 I: Integer;
begin
 I := BufSize;
 while I > 0 do
 begin
   if not (Text[0] in ["0".."f"]) or not (Text[1] in ["0".."f"]) then Break;
   Buffer[0] := Char((Convert[Text[0]] shl 4) + Convert[Text[1]]);
   Inc(Buffer);
   Inc(Text, 2);
   Dec(I);
 end;
 Result := BufSize - I;
end;



 
Пусик ©   (2006-08-15 23:12) [27]

> tesseract ©   (15.08.06 22:40) [24]
> tesseract ©   (15.08.06 21:58) [21]

...Пусик решил опять всех покозлить...
перегруз у меня :-)


Тогда не надо проблемы с больной головы на здоровую перекладывать(т.е. на автора). Из топика всё ясно и понятно - что имел ввиду автор. Если кто-то не в состоянии понять вопроса, то автор в том не виноват.


> Kolan ©   (15.08.06 22:59) [25]
> > доказал преподователь по теории чисел в 1998 годуНу вообщем
> Hex - система счисления.


Из топика всё ясно и понятно - что имел ввиду автор. Если кто-то не в состоянии понять вопроса, то автор в том не виноват.


 
Kolan ©   (2006-08-15 23:37) [28]


> Пусик решил опять всех покозлить.

Это он? 8-/


 
Германн ©   (2006-08-16 00:24) [29]


> Хотя для достаточно длинной строки я бы использовал код
> HexToBin из более свежих версий Delphi.

Ну так уж если сказал assembler, так и приводи ассемблерный код. Иначе "злобн(ый)ая Пусик опять скажет о "неэффективности". :-)


 
Шпиён   (2006-08-16 00:43) [30]


> Германн ©   (16.08.06 00:24) [29]

хочешь?
Ассемблерный вариант в D6 закомментирован -)

Delphi5 (Classes.pas)


function HexToBin(Text, Buffer: PChar; BufSize: Integer): Integer; assembler;
asm
       PUSH    ESI
       PUSH    EDI
       PUSH    EBX
       MOV     ESI,EAX
       MOV     EDI,EDX
       MOV     EBX,EDX
       MOV     EDX,0
       JMP     @@1
@@0:    DB       0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
       DB      -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
       DB      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
       DB      -1,10,11,12,13,14,15
@@1:    LODSW
       CMP     AL,"0"
       JB      @@2
       CMP     AL,"f"
       JA      @@2
       MOV     DL,AL
       MOV     AL,@@0.Byte[EDX-"0"]
       CMP     AL,-1
       JE      @@2
       SHL     AL,4
       CMP     AH,"0"
       JB      @@2
       CMP     AH,"f"
       JA      @@2
       MOV     DL,AH
       MOV     AH,@@0.Byte[EDX-"0"]
       CMP     AH,-1
       JE      @@2
       OR      AL,AH
       STOSB
       DEC     ECX
       JNE     @@1
@@2:    MOV     EAX,EDI
       SUB     EAX,EBX
       POP     EBX
       POP     EDI
       POP     ESI
end;


 
Пусик ©   (2006-08-16 00:52) [31]


> Германн ©   (16.08.06 00:24) [29]


Код хоть и неоптимальный, но вполне имеет право на жизнь. Наглядный и простой.
Там, где нет особых требований к скорости выполнения кода, вполне подойдет.

PS.
Я не "злобная". Я белая и пушистая, пока меня не трогают.


 
Германн ©   (2006-08-16 01:01) [32]


> Шпиён   (16.08.06 00:43) [30]
>
>
> > Германн ©   (16.08.06 00:24) [29]
>
> хочешь?
> Ассемблерный вариант в D6 закомментирован -)
>

Да я то не хочу. Но раз уж ты назвался груздем, так и полезай туда. :-) Залез. Вижу.


 
Германн ©   (2006-08-16 01:06) [33]


> Пусик ©   (16.08.06 00:52) [31]
>
>
> > Германн ©   (16.08.06 00:24) [29]
>
>
> Код хоть и неоптимальный, но вполне имеет право на жизнь.
>  Наглядный и простой.
> Там, где нет особых требований к скорости выполнения кода,
>  вполне подойдет.

Ну так приведи "оптимальный" код. Никто не будет возражать.

>
> PS.
> Я не "злобная". Я белая и пушистая, пока меня не трогают.
>

Дык я и не считал тебя злобной! :-)
Это всё

> tesseract ©   (15.08.06 21:58) [21]

и

> Kolan ©   (15.08.06 23:37) [28]


 
Пусик ©   (2006-08-16 01:08) [34]


> Германн ©   (16.08.06 01:06) [33]
> > Пусик ©   (16.08.06 00:52) [31]> > > > Германн ©   (16.
> 08.06 00:24) [29]> > > Код хоть и неоптимальный, но вполне
> имеет право на жизнь.>  Наглядный и простой.> Там, где нет
> особых требований к скорости выполнения кода,>  вполне подойдет.
> Ну так приведи "оптимальный" код. Никто не будет возражать.
>


Так в [7] код достаточно оптимальный. Хотя вот сейчас думаю, как можно еще оптимизировать.


 
Шпиён   (2006-08-16 01:11) [35]


> Хотя вот сейчас думаю, как можно еще оптимизировать

Ну, для начала я бы не вычислял StrLen(s)div 2 дважды. -)


 
Шпиён   (2006-08-16 01:22) [36]

И еще передал бы в HexToStr не PChar, а const строку, и вообще не "вычислял" бы длину буфера таким способом -)
Попробовал бы воспользоваться Lenght (более универсальный способ) или получить длину строки примерно как integer(pointer(integer(pointer(s))-4)^)
И, возможно, использовал бы сдвиг вправо вместо деления нацело -)


 
Шпиён   (2006-08-16 01:40) [37]

Что-то вроде такого:

function HexToStr(const s:string):string;
var Len:integer;
begin
  Len:=integer(pointer(integer(pointer(s))-4)^) shr 1;
  SetLength(Result,Len);
  SetLength(Result,HexToBin(pchar(s), pchar(result), Len));
end;


 
KilkennyCat ©   (2006-08-16 03:07) [38]

Есть способ еще проще.


 
Пусик ©   (2006-08-16 03:22) [39]


> KilkennyCat ©   (16.08.06 03:07) [38]
> Есть способ еще проще.


Подавай его сюда.
Если проще и быстрее, то совсем хорошо-)


 
Пусик ©   (2006-08-16 03:24) [40]


> KilkennyCat ©   (16.08.06 03:07) [38]


По крайней мере, код Шпиёна из [37] весьма быстр.


 
Fay ©   (2006-08-16 04:24) [41]

2 Шпиён   (16.08.06 1:40) [37]
Это называется "очень сильное колдунство"
Что, по-твоему выдаст HexToStr("") ?


 
Fay ©   (2006-08-16 04:32) [42]

А прирост скорости какой большой! Сдуреть просто...
function HexToStr(const s : string) : string;
var
 Len : integer;
begin
 Len := integer(pointer(integer(pointer(s)) - 4)^) shr 1;
 SetLength(Result, Len);
 SetLength(Result, HexToBin(pchar(s), pchar(result), Len));
end;

function HexToStr2(const s : string) : string;
var
 Len : integer;
begin
 Len := Length(s) div 2;
 SetLength(Result, Len);
 SetLength(Result, HexToBin(pchar(s), pchar(result), Len));
end;

procedure TForm1.Button1Click(Sender : TObject);
var
 i : Integer;
 tc : DWORD;
 s : string;
begin
 s := "30313233343536373839";
 tc := GetTickCount;
 for i := 0 to 999999 do
   s := Copy(s + HexToStr(s), 1, 20);
 ShowMessage(Format("%d", [GetTickCOunt - tc]));
end;


 
Шпиён   (2006-08-16 05:24) [43]


> Fay ©   (16.08.06 04:24) [41]
> 2 Шпиён   (16.08.06 1:40) [37]
> Это называется "очень сильное колдунство"
> Что, по-твоему выдаст HexToStr("") ?

"Что-то вроде такого" не означает "сделай точно так же без всяких проверок входных данных" -)
HexToStr("") в таком варианте выдаст AV.

Если ты заметил, в [36] написано

Попробовал бы воспользоваться Lenght (более универсальный
способ)
или получить длину строки примерно как integer(pointer(integer(pointer(s))- 4)^)
И, возможно, использовал бы сдвиг вправо вместо деления
нацело -)

Основная мысль была - заменить StrLen.
[37]  просто иллюстрация к [36].


 
Шпиён   (2006-08-16 05:57) [44]


> А прирост скорости какой большой! Сдуреть просто...

По производительности (компилятор D6, про другие ничего не могу сказать) варианты
1) Len:=Lenght(s) div 2;
2) Len:=integer(pointer(integer(pointer(s))-4)^) shr 1;
должны быть примерно одинаковы:


1) Len:=Lenght(s) div 2;

mov eax,[ebp-$04]
call@StrLen
sar eax,1

@StrLen:
test eax,eax
jz +$03
mov eax,[eax-$04]
ret

2) Len:=integer(pointer(integer(pointer(s))-4)^) shr 1;

mov eax,[ebp-$04]
sub eax,$04
jno +$05
call @IntOver
mov  eax,[eax]
shr eax,1

ps
И оба будут быстрее, чем [7]

function StrLen(const Str: PChar): Cardinal; assembler;
asm
       MOV     EDX,EDI
       MOV     EDI,EAX
       MOV     ECX,0FFFFFFFFH
       XOR     AL,AL
       REPNE   SCASB
       MOV     EAX,0FFFFFFFEH
       SUB     EAX,ECX
       MOV     EDI,EDX
end;



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2006.09.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.039 c
6-1145086748
ГостьНомер
2006-04-15 11:39
2006.09.03
indy-компонент tidHttp, ошибка 411 Length Required


9-1134243326
Click
2005-12-10 22:35
2006.09.03
DelphiX


3-1151326267
j_a_g_o
2006-06-26 16:51
2006.09.03
ADO+MS SQL + Image blob = ?


2-1155626458
barakuda
2006-08-15 11:20
2006.09.03
EhLib+фильтрация


15-1154508050
Nic
2006-08-02 12:40
2006.09.03
МТС спятила?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский