C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[919] [String] BinToHexEx
장성호 [nasilso] 16166 읽음    2009-09-24 21:07
가끔 Binary파일의 TMemo컴포넌트에 읽어오면

왜 EditPlus나 다른 외부 에디터 처럼 Hex로 안보이냐는 질문이 올라오는 경우가 있다.


당연한것을 .....   

이걸 모르는 이에게 설명하기란 참 쉽지 않는것 같다.


여튼 그것을 설명하려는 것이 아니구...


Binary를 Hex-String으로 변환해주는 VCL함수가 있다.
Classes 유닛에 BinToHex 라고...
그 반대 함수는 HexToBin 이라고 있다.

procedure BinToHex(Buffer, Text: PChar; BufSize: Integer); assembler;
const
  Convert: array[0..15] of Char = '0123456789ABCDEF';
var
  I: Integer;
begin
  for I := 0 to BufSize - 1 do
  begin
    Text[0] := Convert[Byte(Buffer[I]) shr 4];
    Text[1] := Convert[Byte(Buffer[I]) and $F];
    Inc(Text, 2);
  end;
end;


그런데 위 BinToHex 는 Binary를 Hex-String으로 만들어 주기는 하는데...
Byte길이만큼 모두 붙여서 만들어 준다.

외부 Editer처럼 중간에 한칸 뛰우고싶은데....
[중간에 한칸 공백문자를 넣어주는 BinToHex]
//BinToHex 함수에서 한칸씩 공백문자 넣는  기능 추가
procedure BinToHexEx(Buffer, Text: PChar; BufSize: Integer); assembler;
const
  Convert: array[0..15] of Char = '0123456789ABCDEF';
var
  I: Integer;
begin
  for I := 0 to BufSize - 1 do
  begin
    Text[0] := Convert[Byte(Buffer[I]) shr 4];
    Text[1] := Convert[Byte(Buffer[I]) and $F];
    Text[2] := ' ';
    Inc(Text, 3);
  end;
  Text[0] :=Char($0);
end;


음 그리고 위에 함수들은 모두 Hex-String이 대문자로만 표현된다.
소문자 Hex-String 으로 표현하려면?
//BinToHexEx 함수에서 소문자로 표시
procedure BinToHexExSmall(Buffer, Text: PChar; BufSize: Integer); assembler;
const
  Convert: array[0..15] of Char = '0123456789abcdef';
var
  I: Integer;
begin
  for I := 0 to BufSize - 1 do
  begin
    Text[0] := Convert[Byte(Buffer[I]) shr 4];
    Text[1] := Convert[Byte(Buffer[I]) and $F];
    Text[2] := ' ';
    Inc(Text, 3);
  end;
  Text[0] :=Char($0);
end;


외부 Editer를 보니 한라인의 중간쯤에 공백(space)를 좀더 둔것 같던데...
라인 중간에 공백(space)추가
//BinToHexEx 함수에서 Line의 중간에 space 추가
procedure BinToHexEx2(Buffer, Text: PChar; BufSize,Half: Integer); assembler;
const
  Convert: array[0..15] of Char = '0123456789ABCDEF';
var
  I: Integer;
begin
  if(BufSize>Half)then
  begin
    for I := 0 to Half - 1 do
    begin
      Text[0] := Convert[Byte(Buffer[I]) shr 4];
      Text[1] := Convert[Byte(Buffer[I]) and $F];
      Text[2] := ' ';
      Inc(Text, 3);
    end;
    Text[0] := ' ';
    Inc(Text, 1);
    for I := Half  to BufSize - 1 do
    begin
      Text[0] := Convert[Byte(Buffer[I]) shr 4];
      Text[1] := Convert[Byte(Buffer[I]) and $F];
      Text[2] := ' ';
      Inc(Text, 3);
    end;
    Text[0] :=Char($0);
  end
  else
  begin
   for I := 0 to BufSize - 1 do
    begin
      Text[0] := Convert[Byte(Buffer[I]) shr 4];
      Text[1] := Convert[Byte(Buffer[I]) and $F];
      Text[2] := ' ';
      Inc(Text, 3);
    end;
    Text[0] :=Char($0);
  end;
end;



------------------------------------------------------------

이제 위함수를 이용하여 File을 읽어와서 TMemo에 뿌려주는 코딩을 하면...
델파이 사용예
procedure TForm1.Button2Click(Sender: TObject);
const
  size: Integer =32;
var
  fs: TFileStream;
  outstr: array [1..3074] of Char;
  buf: array [1..1024] of Char;
  str: String;
  len: Integer;
  lst: TStringList;
  half: Integer;
begin
  half:= size div 2 ;
  BinToHex

  if OpenDialog1.Execute() then
  begin
    fs:= TFileStream.Create(OpenDialog1.FileName,0);
    lst:= TStringList.Create;
    len:=fs.Read(buf,size);
    while(len<>0) do
    begin
      BinToHexEx2(@buf[1],@outstr[1],len,half);
      lst.Add(String(outstr));
      len:=fs.Read(buf,size);
    end;
    Memo1.Lines.Assign(lst);
    lst.free;
    fs.free;
  end;
end



C++Builder사용예
//C++Builder에서는 위에 BinToHexXX 함수들을 따로 pas 파일로 저장한후에
//C++Builder 프로젝트에 포함하시구
//다음과 같이 include해서 사용하시면 됩니다.
#include "uHexUtils.hpp"
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    if(OpenDialog1->Execute())
    {
        char outstr[3074];
        char buf[1024];
        int len;
        int size=32;
        int half=size/2;

        TFileStream *fs = new TFileStream(OpenDialog1->FileName,0);
        if(fs==NULL)return;

        TStringList *lst=new TStringList;

        len=fs->Read(buf,size);
        while(len>0)
        {
            BinToHexEx2(buf,outstr,len,half);
            lst->Add(String(outstr));
            len=fs->Read(buf,size);
        }
        Memo1->Lines->Assign(lst);
        lst->Free();
        fs->Free();
    }
}
//---------------------------------------------------------------------------
 



첨부파일은 아래그림과
그림이 나오는 C++Builder프로젝트입니다.



참조
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=362
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=785

그럼...
크레브 [kkol]   2009-09-24 23:11 X
게시판은 C++빌더 팁&트릭 인데.. 소스 코드는 전부 파스칼이네요 ~~~ ^^;
장성호 [nasilso]   2009-09-25 01:33 X
죄송합니다. ㅋㅋ
Delphi 소스를 간단히 수정해서 만든것이라서..
C++Builder사용 예제도 추가로 올립니다.

+ -

관련 글 리스트
919 [String] BinToHexEx 장성호 16166 2009/09/24
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.