From: anon@anon.org (anon)
Subject: Re: Base64-Encoding
Date: Fri, 19 Oct 2007 19:40:56 GMT
Date: 2007-10-19T19:40:56+00:00 [thread overview]
Message-ID: <cL7Si.240401$ax1.92228@bgtnsc05-news.ops.worldnet.att.net> (raw)
In-Reply-To: 20071019085934.7c1a525f@cube.tz.axivion.com
In my last post I answer about ENDIAN.
Now for two algorithms to convert data to Base64:
-- --------------------------------------------------------
-- Base64.ads
--
--
-- For conversion -- The use of a 4 byte array is faster since the CPUs
-- of today normally use 8-bits (quarter word) and
-- actually have quarter word storage instructions.
--
--
-- The usage of packed record requires extra
-- code to be added to perform the record packing
-- which will require more cpu cycles.
--
-- Exception would be if your working on a older
-- system like the 1108 9-bit "Univac" (now called
-- "Unisys" ) of the 1970s which had 3-bits, 6-bits
-- and 9-bits access instructions.
--
package Base64 is
-- -------------------------- --
-- TYPE: Base 64 Basics Types --
-- -------------------------- --
--
-- build the 6 bit
--
type Bit_6 is mod 2 ** 6 ;
--
-- Base_64 String Array
--
type Base64_String is new String ( 1..4 ) ;
-- --------------------------------------- --
-- TYPE: Base 64 Basics using 4 byte array --
-- --------------------------------------- --
--
-- packed Bit_6 into 4 bytes
--
type Base64_Array is array ( 0 .. 3 ) of Bit_6 ;
-- ----------------------------------------- --
-- TYPE: Base 64 Basics using 3 byte records --
-- ----------------------------------------- --
--
-- packed Bit_6 into 3 bytes
--
-- ------------------------------ --
-- TYPE: Base 64 Conversion Types --
-- ------------------------------ --
--
-- Base_64_Descriptor is used in converting 8 bit
-- characters to 6 bits ;
--
type Base_64_Descriptor is record
Value_3 : Bit_6 ;
Value_2 : Bit_6 ;
Value_1 : Bit_6 ;
Value_0 : Bit_6 ;
end record ;
--
-- insure 3 byte usage for Character_Descriptor ;
--
pragma pack ( Base_64_Descriptor ) ;
-- ------------------------------- --
-- TYPE: Data Conversion Functions --
-- ------------------------------- --
--
-- 4 byte version
--
function Coding ( B_String : Base64_String )
return Base64_Array ;
function Coding ( B_Array : Base64_Array )
return Base64_String ;
--
-- 3 byte version
--
function Coding ( B_String : Base64_String )
return Base_64_Descriptor ;
function Coding ( B_Array : Base_64_Descriptor )
return Base64_String ;
--
-- Obtain conversion character
--
function Base64_Character ( C : Character ) return Character ;
end Base64 ;
-- --------------------------------------------------------
-- Base64.adb
--
with Interfaces ;
use Interfaces ;
with Ada.Unchecked_Conversion ;
package body Base64 is
--
-- Base_64 Character Set ;
--
Characters : array ( Character range ASCII.Nul .. '?' ) of
Character :=
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" &
"abcdefghijklmnopqrstuvwxyz" &
"0123456789+/" ;
-- ------------------------------ --
-- TYPE: Base 64 Conversion Types --
-- ------------------------------ --
--
-- Character_Descriptor is used in converting 8 bit
-- characters to 6 bits ;
--
type Character_Descriptor is record
unused : Unsigned_8 range 0..3 ;
Value : Bit_6 ;
end record ;
--
-- set bit order
--
for Character_Descriptor use record
unused at 0 range 6..7 ;
Value at 0 range 0..5 ;
end record ;
--
-- insure 1 byte usage for Character_Descriptor ;
--
pragma pack ( Character_Descriptor ) ;
-- ------------------------------- --
-- TYPE: Data Conversion Functions --
-- ------------------------------- --
function Char_8_To_Char_6 is new Ada.Unchecked_Conversion
( Character, Character_Descriptor ) ;
function Char_6_To_Char_8 is new Ada.Unchecked_Conversion
( Character_Descriptor, Character ) ;
-- -------------- --
-- 4 byte version --
-- -------------- --
function Coding ( B_String : Base64_String ) return Base64_Array is
Temp : Base64_Array ;
Work : Character_Descriptor ;
begin -- Coding
Work := Char_8_To_Char_6 ( B_String ( 4 ) ) ;
Temp ( 3 ) := Work.Value ;
Work := Char_8_To_Char_6 ( B_String ( 3 ) ) ;
Temp ( 2 ) := Work.Value ;
Work := Char_8_To_Char_6 ( B_String ( 2 ) ) ;
Temp ( 1 ) := Work.Value ;
Work := Char_8_To_Char_6 ( B_String ( 1 ) ) ;
Temp ( 0 ) := Work.Value ;
return Temp ;
end Coding ;
function Coding ( B_Array : Base64_Array ) return Base64_String is
Temp : Base64_String ;
Work : Character_Descriptor ;
begin -- Coding
Work.unused := 0 ; -- to insure value of conversion ;
Work.Value := B_Array ( 3 ) ;
Temp ( 4 ) := Char_6_To_Char_8 ( Work ) ;
Work.Value := B_Array ( 2 ) ;
Temp ( 3 ) := Char_6_To_Char_8 ( Work ) ;
Work.Value := B_Array ( 1 ) ;
Temp ( 2 ) := Char_6_To_Char_8 ( Work ) ;
Work.Value := B_Array ( 0 ) ;
Temp ( 1 ) := Char_6_To_Char_8 ( Work ) ;
return Temp ;
end Coding ;
-- -------------- --
-- 3 byte version --
-- -------------- --
function Coding ( B_String : Base64_String )
return Base_64_Descriptor is
Temp : Base_64_Descriptor ;
Work : Character_Descriptor ;
begin -- Coding
Work := Char_8_To_Char_6 ( B_String ( 4 ) ) ;
Temp.Value_3 := Work.Value ;
Work := Char_8_To_Char_6 ( B_String ( 3 ) ) ;
Temp.Value_2 := Work.Value ;
Work := Char_8_To_Char_6 ( B_String ( 2 ) ) ;
Temp.Value_1 := Work.Value ;
Work := Char_8_To_Char_6 ( B_String ( 1 ) ) ;
Temp.Value_0 := Work.Value ;
return Temp ;
end Coding ;
function Coding ( B_Array : Base_64_Descriptor )
return Base64_String is
Temp : Base64_String ;
Work : Character_Descriptor ;
begin -- Coding
Work.unused := 0 ; -- to insure value of conversion ;
Work.Value := B_Array.Value_3 ;
Temp ( 4 ) := Char_6_To_Char_8 ( Work ) ;
Work.Value := B_Array.Value_2 ;
Temp ( 3 ) := Char_6_To_Char_8 ( Work ) ;
Work.Value := B_Array.Value_1 ;
Temp ( 2 ) := Char_6_To_Char_8 ( Work ) ;
Work.Value := B_Array.Value_0 ;
Temp ( 1 ) := Char_6_To_Char_8 ( Work ) ;
return Temp ;
end Coding ;
--
-- Obtain conversion 8-bit character
--
function Base64_Character ( C : Character ) return Character is
begin -- Base64_Character
return Characters ( C ) ;
end Base64_Character ;
end Base64 ;
-- --------------------------------------------------------
-- Test64.adb -- Test program
--
with Base64 ;
with Ada.Text_IO ;
with Ada.Integer_Text_IO ;
use Ada.Text_IO ;
use Ada.Integer_Text_IO ;
procedure test64 is
a : Base64.Base64_String := "1234";
b : Base64.Base_64_Descriptor ;
c : Base64.base_64_Descriptor := ( 10, 20, 30, 40 ) ;
d : Base64.base64_Array := ( 00, 01, 02, 03 ) ;
e : Base64.Base64_String ;
f : Base64.base64_Array ;
begin
--
-- Test using 4 byte array
--
Put ( d'size ) ;
New_Line ;
Put ( e'size ) ;
New_Line ;
e := Base64.Coding ( d ) ;
f := Base64.Coding ( e ) ;
Put ( "Data : " ) ;
Put ( Base64.Base64_Character ( e ( 1 ) ) ) ;
Put ( Base64.Base64_Character ( e ( 2 ) ) ) ;
Put ( Base64.Base64_Character ( e ( 3 ) ) ) ;
Put ( Base64.Base64_Character ( e ( 4 ) ) ) ;
New_Line ;
b := Base64.Coding ( a ) ;
Put ( a'size ) ;
New_Line ;
Put ( b'size ) ; -- 24 aka 3 byte pack record
New_Line ;
--
-- Test using packed 3 byte record
--
a := Base64.Coding ( c ) ;
Put ( "Data : " ) ;
Put ( Base64.Base64_Character ( a ( 1 ) ) ) ;
Put ( Base64.Base64_Character ( a ( 2 ) ) ) ;
Put ( Base64.Base64_Character ( a ( 3 ) ) ) ;
Put ( Base64.Base64_Character ( a ( 4 ) ) ) ;
New_Line ;
end Test64 ;
In <20071019085934.7c1a525f@cube.tz.axivion.com>, Stefan Bellon <sbellon@sbellon.de> writes:
>On Fr, 19 Okt, anon wrote:
>
>> function To_Base64 is new Ada.Unchecked_Conversion
>> ( Source => Unsigned_8,
>> Target => base64_descriptor ) ;
>>
>> function From_Base64 is new Ada.Unchecked_Conversion
>> ( Target => Unsigned_8,
>> Source => base64_descriptor ) ;
>
>But this only converts one whole byte (aka Unsigned_8) into a Six_Bits
>by ignoring the two top-bits. This does not help with my original idea
>of overlaying a packed array of 6-bit elements over an array of 8-bit
>characters and then looping over the 6-bit elements to do the
>conversion in a simple loop, character by character.
>
>> In 2001 Tom Moran created a Ada BASE64 package which is archived at
>>
>> http://www.adapower.com/index.php?Command=Class&ClassID=Algorithms&CID=257
>>
>> have a look at it. I a quick look it kind of suggest that the endian
>> for Six_Bits is not important.
>
>Yes, I know this package. But it handles three bytes in the original in
>one go and always encodes three bytes into four 6-bits.
>
>As I mentioned in my first posting, I am aware of the solutions to do
>the actual conversion that exist (and already have been discussed a
>few times here in the group). I was just wondering whether my idea
>of overlaying the two arrays could be easily "fixed" so that it works.
>
>But thanks for your ideas!
>
>--
>Stefan Bellon
prev parent reply other threads:[~2007-10-19 19:40 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-15 14:12 Base64-Encoding Stefan Bellon
2007-10-15 14:46 ` Base64-Encoding Jacob Sparre Andersen
2007-10-15 14:54 ` Base64-Encoding Stefan Bellon
2007-10-15 15:14 ` Base64-Encoding Jacob Sparre Andersen
2007-10-15 15:37 ` Base64-Encoding Robert A Duff
2007-10-15 15:40 ` Base64-Encoding Jean-Pierre Rosen
2007-10-15 16:39 ` Base64-Encoding Stefan Bellon
2007-10-16 10:42 ` Base64-Encoding Stephen Leake
2007-10-17 14:07 ` Base64-Encoding Stefan Bellon
2007-10-17 15:09 ` Base64-Encoding Adam Beneschan
2007-10-17 18:15 ` Base64-Encoding Larry Kilgallen
2007-10-15 18:24 ` Base64-Encoding Adam Beneschan
2007-10-19 2:43 ` Base64-Encoding anon
2007-10-19 4:33 ` Base64-Encoding anon
2007-10-19 7:35 ` Base64-Encoding Jean-Pierre Rosen
2007-10-19 6:59 ` Base64-Encoding Stefan Bellon
2007-10-19 19:40 ` anon [this message]
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox