Solved

Convert Hex value to String

Posted on 2008-11-03
22
1,431 Views
Last Modified: 2012-05-05
I need a function that convert HEX string to Ascii string or readable string,
anyody help me?

So hex-string :#$2A#$86#$48#$86#$F7#$0D#$02#$05

thanks.

0
Comment
Question by:M-Khorsandi
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 6
  • 4
  • +2
22 Comments
 
LVL 28

Expert Comment

by:2266180
ID: 22866213
you will see garbage because your hex string rep[resents binary data.
function hexstos(s:string):string;
var i:integer;
    t:string;
begin
  result:='';
  if s='' then
    exit;
  assert(s[1]='#');
  i:=2;
  repeat
    T:='';
    while (i<=length(s)) and (s[i]<>'#') do
    begin
      t:=t+s[i];
      inc(i);
    end;
    inc(i);
    result:=result+chr(strtoint(t));
  until i>=length(s);
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  showmessage(hexstos('#$2A#$86#$48#$86#$F7#$0D#$02#$05'));
end;

Open in new window

0
 
LVL 19

Assisted Solution

by:MerijnB
MerijnB earned 20 total points
ID: 22866239
I think you mean something like this:
function StrDisplayHex(Data: string): string;
var i: integer;
begin
 result := '';
 
 for i := 1 to Length(Data) do
  result := result + ' $' + IntToHex(Ord(Data[i]), 2);
 
 result := Trim(result);
end;

Open in new window

0
 
LVL 45

Expert Comment

by:aikimark
ID: 22866612
I think we've missed the best solution.

* use COPY() to get the three characters that represent the hex literal
* use INC(i, 4) to position to the next set
* depending on the length of the string, we might also consider minimizing the number of concatenations while building the result.
function StrDisplayHex(Data: string): string;
var i: integer;
begin
 i := 2;
 repeat 
  result := result + Chr(StrToInt(Copy(Data, i, 3)));
  inc(i, 4);
 Until i > Length(Data);
end;

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 28

Expert Comment

by:2266180
ID: 22866693
if you're looking for speed then the next one is much better:
function hexstos(s:string):string;
var i, j, c:integer;
    a,b:pchar;
begin
  setlength(result, length(s) div 4);
  a:=pchar(s);
  b:=pchar(result);
  i:=3;
  j:=1;
  c:=length(result);
  while j<=c do
  begin
    b[j]:=char(byte(a[i])*16+byte(a[i+1]));
    i:=i+4;
    j:=j+1;
  end;
end;

Open in new window

0
 
LVL 45

Expert Comment

by:aikimark
ID: 22866956
@ciuly

Aren't we all looking for speed?!? :-)
Why else use Delphi?

Question: Why i := i + 4; instead of Inc(i, 4) ?
0
 
LVL 28

Expert Comment

by:2266180
ID: 22867224
>> Aren't we all looking for speed?!? :-)

not necessarely. if you want super speed, you will use C (not c++) or ASM.

>> Question: Why i := i + 4; instead of Inc(i, 4) ?

look at the dissasembly. inc is a procedure. you waste a few machine cycles by calling a procedure and returning from it :P

>> Why else use Delphi?

because delphi is RAD. sure, we want speed, but primarely, we want it at development stage. THEN, we can do optimizations, where possible. either speed optimizations or memory optimizations or both. depending on the problem in hand.
and when you want speed in delphi, the first thing you eliminate as much as possible are the delphi string routines. next, optimize all memory managements plus other stuff.
0
 
LVL 45

Expert Comment

by:aikimark
ID: 22867366
I'd have thought the compiler to be more optimized (smarter) than that, but Inc() can also vary a range of ordinal values, so I understand the overhead.
0
 
LVL 6

Expert Comment

by:JosephGlosz
ID: 22870004
Hmm, regarding 'inc' ..  I wonder why the Delphi Help has said the following about "inc" for years:

X increments by 1, or by N if N is specified; that is, Inc(X) corresponds to the statement X := X + 1, and Inc(X, N) corresponds to the statement X := X + N. However, Inc generates optimized code and is especially useful in tight loops.

Has Borland / Inprise / CodeGear / Embarcadero overlooked this for all these years? Shouldn't someone write up a trouble ticket for this? At least, to fix the help files?

I decided to test this with the following simple program. Button1 runs an "inc" loop BIG times (in this case a billion times). Button2 runs i := i + 4 loop the same number of times.  With compiler optimization both off and on, the inc loop generally runs a few ms faster. Results vary a bit because your Windows system is doing other things when you click the buttons. But I get results like 3266 ms versus 3282 ms (optimization off) and 466 ms vs 484 ms (optimization on).


const
  BIG = 1000000000;

procedure TForm1.Button1Click(Sender: TObject);
var
  i,j: Longint;
  T1,T2: TDateTime;
begin
 j := 0;
 T1 := Now;
 for i := 1 to BIG do
   inc(j,4);
 T2 := Now;
 Label1.Caption := format('Time Dif = %d ms',[MillisecondsBetween(T1,T2)]);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i,j: Longint;
  T1,T2: TDateTime;
begin
 j := 0;
 T1 := Now;
 for i := 1 to BIG do
   j := j + 4;
 T2 := Now;
 Label2.Caption := format('Time Dif = %d ms',[MillisecondsBetween(T1,T2)]);
end;




0
 
LVL 28

Expert Comment

by:2266180
ID: 22870334
I didn't know about that :)
but you are right, inc generates optimized code (meaning there is no procedure call/ret as I incorrectly assumed (wallbash)).
but the weird thing is that both inc(var, 4) and var:=var+4 generate the same asm code (add <some 32 bit register>, 4). so from this point of view, they should be of the same speed.
0
 
LVL 45

Expert Comment

by:aikimark
ID: 22870377
Vindication!   :-)
0
 
LVL 6

Expert Comment

by:JosephGlosz
ID: 22870462
Chewie, I agree with you. Maybe they *are* the the same speed. If you iterate something a billion times, and the speed difference amounts to just a few milliseconds, I'd consider them pretty much equal. Especially given that there might be some 30 or more other processes running in Windows at one time.
0
 
LVL 45

Expert Comment

by:aikimark
ID: 22878464
@ciuly

I've got a newb question for you about your fast solution.
What does the compiler do when a[i] is 'A'..'F'?

I can understand where the compiler might correctly interpret '0'..'9', but might just as easily use the ASCII character value of a[i], which would result in incorrect byte value calculations (and wrong strings).
0
 
LVL 28

Accepted Solution

by:
2266180 earned 20 total points
ID: 22878890
that's not actually the problem. I was doing typecasting, so byte('0') is actualy ord('0') and not 0.

correct way would be (written directly in browser, hope it compiles)

function hexstos(s:string):string;
var i, j, c:integer;
    a,b:pchar;
    t1,t2:byte;
begin
  setlength(result, length(s) div 4);
  a:=pchar(s);
  b:=pchar(result);
  i:=3;
  j:=1;
  c:=length(result);
  while j<=c do
  begin
    t1:=byte(a[i])-$30;
    if t1>9 then
      t1:=t1-$10+10;// uppercase
    if t1>15 then
      t1:=t1-$10;// lowercase
    t2:=byte(a[i+1])-$30;
    if t2>9 then
      t2:=t2-$10+10;// uppercase
    if t2>15 then
      t2:=t2-$10;// lowercase
    b[j]:=char(t1*16+t2);
    i:=i+4;
    j:=j+1;
  end;
end;

obviously I don't know how optimum this is. I am working on something else right now and can't switch. but if I am correct, precalculated arrays will be faster. that is one "big" array from '0' to 'f' in which the relevant elements are initialized with their coresponding values. (array['0'..'f'] of byte; for whomever wants to try)
0
 
LVL 45

Expert Comment

by:aikimark
ID: 22879479
I was thinking of array, ordinal, or enum solutions as well.  Somewhere in the deep recesses of my memory is an example where values are translated into a zero-based value without having to do any initialization or value-matching lookups.

I think it is an adequate assumption to only include the upper case 'A'..'F' values along with the numeric characters.

I would also replace *16 with shl( , 4)
0
 
LVL 6

Expert Comment

by:JosephGlosz
ID: 22879498
another common way is to use the pos function to return the correct byte equivalent of a hex digit.

S := '1e';  // sample hex string
i := HexToByte(S);  

function HexToByte(S: string): integer;
const
  HEX = '0123456789ABCDEF';
begin
  S := UpperCase(S);  // just in case
  result := 0;
  for i := 1 to length(S) do  // probably should limit to a small length
    result := result*16 + succ(pos(S[i],HEX));  //no error check here
end;






 
0
 
LVL 28

Expert Comment

by:2266180
ID: 22879795
>> I would also replace *16 with shl( , 4)

that is already done by the compiler if optimizations are on. but good call, for the case when it's not on.

joesph, that's not optimal :) for every iteration, you will call the pos fnciton, which also requires creating a stack for it (since it has at least one variable) plus copying the HEX string on that stack (!!!) and then doing a not at all optimal search, even if the string is short. I would say it's maybe 5 to 10 times slower then a lookup table.
0
 
LVL 6

Expert Comment

by:JosephGlosz
ID: 22879867
you are absolutely right. Far, far from optimal.  To find the 'F' in the string, 'pos' has to make 15 other comparisons first.

 I sure wouldn't use it in a big loop or anywhere else where it's called frequently.

On the other hand, if we used Microsoft's philosophy, we wouldn't care about the inefficiency, and simply let the next generation of processors make things fast enough for us... :)
0
 
LVL 45

Expert Comment

by:aikimark
ID: 28172287
I recommend a points split:

http:#22878890  Author:ciuly
http:#22866239  Author:MerijnB
http:#22866612  Author:aikimark
http:#22879498  Author:JosephGlosz
0
 
LVL 100

Expert Comment

by:mlmcc
ID: 28177046
That was my attempt.

 40 points can only be split into 2 (20 point minimum on a split)

Please pick 2 of the answers.

mlmcc
0
 
LVL 45

Expert Comment

by:aikimark
ID: 28187830
http:#22878890  Author:ciuly
http:#22866239  Author:MerijnB
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question