Avatar of Marco Gasi
Marco Gasi
Flag 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.
AssemblyDelphi

Avatar of undefined
Last Comment
Marco Gasi

8/22/2022 - Mon
Geert G

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 ...
Geert G

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
Geert G

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
Geert G

ow forget, add

uses StrUtils;
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
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...
Marco Gasi

ASKER
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
Marco Gasi

ASKER
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?
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Marco Gasi

ASKER
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 :-)
Marco Gasi

ASKER
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?
Marco Gasi

ASKER
I think I can try to convert binary strings to their Integer value and get the correspondent char using Chr function, I don't?
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Marco Gasi

ASKER
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
Marco Gasi

ASKER
A note about FillNibbles function: you was totally right, of course. I tested nothing: simply, my code always added a zero! :-(
Marco Gasi

ASKER
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.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.