On Base64

*duh, dah lama nggak update blog saking sibuknya (cari alesan)*

Beberapa waktu yang lalu ada permintaan untuk melakukan encoding/decoding ke format base64. karena waktu yang mendesak dan jumlah item requirement yang banyak maka alternatif pertama adalah mencari kode public domain di internet. ternyata tidak satupun yang bisa dipakai (pada saat yang sempit itu). hambatannya bermacam-macam, mulai dari hasil encoding yang tidak sesuai, atau hasil decoding yang beda dengan acuan. setelah duduk sebentar sambil melototin lagi halaman wikipedia yang mendeskripsikan aturan pengkodean basis64 akhirnya langkah terakhir malah bikin sendiri fungsi yang sesuai dengan spek (teks dari/ke base64, binary(variabel bertipe ataupun byte stream) dari/ke base64).

bagi yang berminat menggunakan, dipersilakan menggunakan kode berikut sebebas-bebasnya (pubdom as no warranty for using).

(*
 * auth : Peb Ruswono Aryan
 * desc : base64 encoding/decoding for delphi
 *)
type
  tbytearr = array of byte;

{ 
	encode64 : Pointer x Nat --> string
	desc: encode binary data to base64 message 
}
function encode64( const v: Pointer; vsize: cardinal ): string;
const
  lut64             = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var
  tribyte           : array[0..2] of byte;
  p                 : PByteArray;
  ci, i             : cardinal;

  function enc3byteto4char( len: integer ): string;
  begin
    result := lut64[1 + tribyte[0] shr 2];
    result := result + lut64[1 + ( ( tribyte[0] and $03 ) shl 4 ) + ( tribyte[1] shr 4 )];
    if len > 1 then
      result := result + lut64[1 + ( tribyte[1] and $0F ) shl 2 + ( tribyte[2] shr 6 )]
    else
      result := result + '=';
    if len > 2 then
      result := result + lut64[1 + tribyte[2] and $3F]
    else
      result := result + '=';
  end;
begin
  p := PByteArray( v );
  ci := 0;
  repeat
    i := 0;
    while i < 3 do begin
      if ci >= vsize then break;
      tribyte[i] := p[ci];
      inc( ci );
      inc( i );
    end;
    result := result + enc3byteto4char( i );
  until ci >= vsize;
end;

{ 
	decode64 : String --> DynamicArray of byte
	desc: decode base64message to binary data (array of byte) 
}
function decode64( msg: string ): TbyteArr;
var
  pb                : array of byte;
  lm, pi            : integer;
  len               : integer;

  function decodechar( c: char; var code: byte ): boolean;
  begin
    result := true;
    case c of
      'A'..'Z': code := ord( c ) - ord( 'A' );
      'a'..'z': code := ord( c ) - ord( 'a' ) + 26;
      '0'..'9': code := ord( c ) - ord( '0' ) + 52;
      '+': code := 62;
      '/': code := 63;
    else
      result := false;
    end;
  end;

  procedure decodeblock( blk: string );
  var
    t, i            : byte;
    w               : dword;
  begin
    w := 0;
    i := 0;
    while i < 4 do begin
      if not decodechar( blk&#91;i + 1&#93;, t ) then break;
      w := w shl 6 + t;
      inc( i );
    end;
    result&#91;pi&#93; := ( w shr 16 ) and $FF;
    inc( pi );
    if pi >= len then exit;
    result[pi] := ( w shr 8 ) and $FF;
    inc( pi );
    if pi >= len then exit;
    result[pi] := ( w and $FF );
    inc( pi );
  end;
begin
  len := length( msg ) * 3 div 4;
  lm := length( msg );
  if msg[lm] = '=' then dec( len );
  if msg[lm - 1] = '=' then dec( len );
  setlength( result, len );
  pi := 0;
  repeat
    decodeblock( copy( msg, 1, 4 ) );
    delete( msg, 1, 4 );
  until length( msg ) <= 0;
end;

{ 
	encode64str : string --> string
	desc: encode text string into base64 message
}
function encode64str( msg: string ): string;
var
  p                 : TByteArr;
  i                 : integer;
begin
  setlength( p, length( msg ) );
  for i := 0 to high( p ) do
    p[i] := ord( msg[i + 1] );
  result := encode64( @p[0], length( p ) );
end;

{ 
	decode64str : string --> string
	desc: decode base64 message containing text
}
function decode64str( msg: string ): string;
var
  p                 : TByteArr;
  i                 : integer;
begin
  result := '';
  p := decode64( msg );
  for i := 0 to length( p ) do
    result := result + chr( p[i] );
end;

4 comments

  1. dodik · April 14, 2009

    saya bingung dengan istilah base64 encode byte
    bagimana sih maksudnya ?

  2. pebbie · April 14, 2009

    @dodik:coba baca link wikipedia yang ada di atas

  3. bro · April 21, 2010

    Cara menggunakannya gimana???

  4. gun · April 21, 2010

    Gmna cra pkainy???

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s