Link to home
Start Free TrialLog in
Avatar of Marco Gasi
Marco GasiFlag for Spain

asked on

How to convert a string or a character to its binary representation

Hi all. This is the chapter 2 of "The incredible adventures of my brain against Assembly language". For learning and training purposes, I'm writeing a small app to help me to memorize conversion table between binary and hexadecinal. Or better, this was at first. The project has grown up and has became more complex. Now I wrote a little piece of code to convert Integer to Binary and viceversa. I found the first function over the Internet and I have just extended it a little:

 
//pad values with zeros to obtain a final string multiple of 4 - regular nibbles
function TForm1.FillNibbles(s: string): string;
var
  r: Integer;
begin
  Result := s;
  r := Length(s) mod 4;
  if r <> 0 then
  begin
    if r = 25 then
      Result := '000' + s
    else if r = 50 then
      Result := '00' + s
    else
      Result := '0' + s;
  end;
end;

//divides string in groupof 4 chars (nibbles separating them by a white space
function TForm1.MakeReadable(s: string): string;
var
  i, counter: Integer;
begin
  mmo2.Lines.Add(s);
  Result := '';
  counter := 1;
  for i := Length(s) downto 1 do
  begin
    if counter < 4 then
    begin
      Result := s[i] + Result;
      Inc(counter);
    end
    else
    begin
      Result := s[i] + Result;
      if i > 1 then
        Result := ' '+ Result;
      counter := 1;
    end;
  end;
end;

// Convert an integer to its binary representation using division by 2 method
function TForm1.MyIntToBin(n: LongInt; Fill: Boolean = True; Readable: Boolean = True): string;
var
  t, r: Integer;
  s: string;
begin
  s := '';
  t := n;
  repeat
    if (t mod 2) = 0 then
      s := '0' + s
    else
      s := '1' + s;
    t := t div 2;
  until t = 0;
  if Fill then
    s := FillNibbles(s);
  if Readable then
    s := MakeReadable(s);
  Result := s;
end;

Open in new window


Here is the my self-written function to convert from binary to Integer:

function TForm1.MyBinToInt(v: string): LongInt;
var
  i, r, p: Integer;
begin
  Result := 0;
  p := 0;
  for i := Length(Trim(v)) downto 1 do
  begin
    r := Round(StrToInt(v[i]) * Power(2, p));
    Inc(p);
    Result := Result + r ;
  end;
end;

Open in new window


Well. Now I would like to understand how I can convert a normal text string to Binary: What is the correct method? I have to take the Integer value of each single char using the ASCII tableand then apply the same method used for numbers? Or there is some other technique?

Thanks to all.
Avatar of Geert G
Geert G
Flag of Belgium image

are you going to be using unicode in the future ?
every character may consist of 1, 2 or 4 bytes ... :)

just so you know what your possible next challenge is ...
your fillnibles function doesn't work ... it's not formatting correctly

anynumber mod 4 only gives 0,1,2 or 3 as result, never 25 or 50
ASKER CERTIFIED SOLUTION
Avatar of Geert G
Geert G
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ow forget, add

uses StrUtils;
Avatar of Marco Gasi

ASKER

Hi Geert. Thanks for your reply.

First, thank for your note about FillNibbles function. I tested in my program and it add the correct num,ber of zeros, but I see you're right about the result of anynumber mod 4. So I could change my function replacing 75, 50 and 25 with 3, 2 and 1... but your function is more elegant, I see this :-)

About your first comment, are you saying that binary representation is different depending on character set (ASCII vs Unicode)? But what I wish is to know which is the logic of the conversion: to convert an integer number to its binary code you can use the divide by two algorithm. I wish to know if there is something equivalent to convert string...
Well, I would like to understand the logic behind this: http://easycalculation.com/ascii-hex.php. I wish only the logic so I can develop a convertion function by my self - and then ask to Geert where is the error ;-)

Thanks
Ok, I found the solution and I post it here if some other is crazy enough to make this type of question.

Effectively using the program hosted in the site I linked above, we can see this:  char 'k' (lowercase) result in this binary string: 0110 1011 - that is the result of a division-by-two iterated on the ASCII value for the 'k' char, 107.

107     odd       -> 1  L.O.
  53,... odd       -> 1
  26,... even     -> 0      
  13,... odd       -> 1
    6,... even     -> 0
    3,... odd       -> 1
    1,... odd       -> 1
    0,...  is zero -> 0  H.O

that is 0110 1011


Dear Geert, this is the second time you try to help me and I would like to award points to you since your comment, not being the solution to my problem, has solved another problem I ignored! I think to have to accept my answer as solution without points and I could post another question about formatting conversion result in order to award you well deserved points. Do you agree with this?
Ah, I forgot... In the ASCII table here http://easycalculation.com/ascii-hex.php what are the first two rows? What are NUL, SOH, STX, ETX, EOT,      ENQ,      ACK... and so on? Can you tell me a resource about this? Thanks a lot :-)
I post here the full code. Simply add to the form 2 Tedit, a TMemo and 2 TButton: the program is simple so I think no other explanation is needed.
procedure TForm1.btnMyInt2BinClick(Sender: TObject);
var
  s: string;
begin
  {se ci sono caratteri numerici e alfabetici raise an error
   se ci sono solo numeri vanno trattati come un Intero
   altrimenti usare la tabella ASCII}
  mmo2.Lines.Clear;
  s := MyIntToBin(StrToInt(edtInt.Text));
//  s := MakeReadable(s);
  mmo2.Lines.Add(s);
end;

function TForm1.FillNibbles(s: string): string;
var
  n: Integer;
begin
  n := Length(s) mod 4;
  if n <> 0 then
    Result := DupeString('0', 4-n) + s
  else
    Result := s;
end;

function TForm1.MakeReadable(s: string): string;
var
  i, counter: Integer;
begin
  Result := '';
  counter := 1;
  for i := Length(s) downto 1 do
  begin
    if counter < 4 then
    begin
      Result := s[i] + Result;
      Inc(counter);
    end
    else
    begin
      Result := s[i] + Result;
      if i > 1 then
        Result := ' '+ Result;
      counter := 1;
    end;
  end;
end;

function TForm1.MyIntToBin(n: LongInt; Fill: Boolean = True): string;
var
  t, r: Integer;
  s: string;
begin
  s := '';
  t := n;
  repeat
    if (t mod 2) = 0 then
      s := '0' + s
    else
      s := '1' + s;
    t := t div 2;
  until t = 0;
  if Fill then
    s := FillNibbles(s);
  Result := s;
end;

procedure TForm1.btnString2BinClick(Sender: TObject);
var
  c: Char;
  i, val: Integer;
  s: string;
begin
  for i := Length(edtInt.Text) downto 1 do
  begin
    c := edtInt.Text[i];
    val := Ord(c);
    s := MyIntToBin(val) + s;
    if i > 1 then
      s := ' ' + s;
  end;
//  s := MakeReadable(s);
  mmo2.Lines.Add(s);
end;


function TForm1.MyBinToInt(v: string): LongInt;
var
  i, r, p: Integer;
begin
  Result := 0;
  p := 0;
  for i := Length(Trim(v)) downto 1 do
  begin
    r := Round(StrToInt(v[i]) * Power(2, p));
    Inc(p);
    Result := Result + r ;
  end;
end;

procedure TForm1.btnMyBin2IntClick(Sender: TObject);
var
  i: LongInt;
begin
  i := MyBinToInt(mmo2.Text);
  edtMyBin2Int.Text := IntToStr(i);
end;

Open in new window


The question now is: hot to convert the binary string to the original text string? Any idea?
I think I can try to convert binary strings to their Integer value and get the correspondent char using Chr function, I don't?
Done: binary to string is accomlished this way:

 
procedure TForm1.btnBin2StringClick(Sender: TObject);
var
  i: Integer;
  s: string;
  c: Char;
  sl: TStringList;
begin
  mmo2.Clear;
  sl := TStringList.Create;
  try
    Split(' ', mmo2.Text, sl);
    for i := 0 to Pred(sl.Count) do
    begin
      c := Chr(MyBinToInt(sl[i]));
      s := s + c;
    end;
  finally
    sl.Free;
  end;
  edtMyBin2Int.Text := s;
end;

Open in new window


Obviously, you have to change components names accordingly to yours.

Cheers
A note about FillNibbles function: you was totally right, of course. I tested nothing: simply, my code always added a zero! :-(
Hi Geert. Thank you very mutch for your help. I decided to award you points because your comment has been very useful. Even if it is not the solution, I think wee have not to be too slavess to burocracy logic and close this question to open another one only to give point.
Hope what I mean be clear enough, since my english is not so good.
Thank you.