comp.lang.ada
 help / color / mirror / Atom feed
* Base64-Encoding
@ 2007-10-15 14:12 Stefan Bellon
  2007-10-15 14:46 ` Base64-Encoding Jacob Sparre Andersen
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Stefan Bellon @ 2007-10-15 14:12 UTC (permalink / raw)


Hi all,

I've been looking through the previous postings of the group and found
two major threads where this topic has already been discussed. But the
proposed solutions were all different to what I was thinking about. I
have thought about the following:


package body Base64 is

   type Six_Bits is mod 2**6;
   for Six_Bits'Size use 6;

   type Six_Bits_Array is array (Natural range <>) of Six_Bits;
   for Six_Bits_Array'Alignment use 1;  --  To overlay over String type.
   for Six_Bits_Array'Component_Size use Six_Bits'Size;
   pragma Pack (Six_Bits_Array);

   Base64_Chars : constant array (Six_Bits) of Character :=
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

   function Encode
     (Data : in String)
     return String
   is
      Padded_Length : constant Natural := ((Data'Length + 2) / 3) * 3;
      --  Pad input data to 3-Byte boundary.

      Base64_Length : constant Natural := Padded_Length / 3 * 4;
      --  Number of six-bit tokens necessary (including padding).

      Six_Bits_Length : constant Natural := (Data'Length * 4 + 2) / 3;
      --  Number of six-bit tokens necessary (without padding).

      Padded_Data : String (1 .. Padded_Length) := (others => ASCII.NUL);
      --  Padded input data.

      Base64_Data : Six_Bits_Array (1 .. Base64_Length);
      for Base64_Data'Address use Padded_Data'Address;
      --  Overlay array of six-bit tokens over the padded input data.

      Result : String (1 .. Base64_Length) := (others => '=');
      --  Output buffer, initialized with '=' tokens for unfilled
      --  end-markers.
   begin
      Padded_Data (1 .. Data'Length) := Data;
      --  Initialize data into padded-data (can't be done with aggregate
      --  in elaboration part, sadly).

      --  Do the actual encoding ...
      for I in 1 .. Six_Bits_Length loop
         Result (I) := Base64_Chars (Base64_Data (I));
      end loop;

      return Result;
   end Encode;

end Base64;


However it looks like this solution has a problem with endianness, in a
way that the wrong 6 bits of the Bytes are used in the conversion.

Is there an easy way to fix this (as I think the rest would be pretty
neat) or is this way of trying to do it, doomed to fail anyway?

-- 
Stefan Bellon



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-15 14:12 Base64-Encoding Stefan Bellon
@ 2007-10-15 14:46 ` Jacob Sparre Andersen
  2007-10-15 14:54   ` Base64-Encoding Stefan Bellon
  2007-10-15 18:24 ` Base64-Encoding Adam Beneschan
  2007-10-19  2:43 ` Base64-Encoding anon
  2 siblings, 1 reply; 17+ messages in thread
From: Jacob Sparre Andersen @ 2007-10-15 14:46 UTC (permalink / raw)


Stefan Bellon wrote:

>       Padded_Data : String (1 .. Padded_Length) := (others => ASCII.NUL);
>       --  Padded input data.
[...]
>    begin
>       Padded_Data (1 .. Data'Length) := Data;
>       --  Initialize data into padded-data (can't be done with aggregate
>       --  in elaboration part, sadly).

Why?  I may have missed something obvious, but I would have thought that

   Padded_Data : String (1 .. Padded_Length) := Data & (others => ASCII.NUL);

would work fine.

> However it looks like this solution has a problem with endianness,
> in a way that the wrong 6 bits of the Bytes are used in the
> conversion.

:-(

> Is there an easy way to fix this (as I think the rest would be
> pretty neat) or is this way of trying to do it, doomed to fail
> anyway?

Is it a problem that section 13.5.3 (Bit Ordering) can handle?

Greetings,

Jacob
-- 
�When in Rome; burn it�                        -- Diziet Sma



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-15 14:46 ` Base64-Encoding Jacob Sparre Andersen
@ 2007-10-15 14:54   ` Stefan Bellon
  2007-10-15 15:14     ` Base64-Encoding Jacob Sparre Andersen
  2007-10-15 15:40     ` Base64-Encoding Jean-Pierre Rosen
  0 siblings, 2 replies; 17+ messages in thread
From: Stefan Bellon @ 2007-10-15 14:54 UTC (permalink / raw)


On Mon, 15 Oct, Jacob Sparre Andersen wrote:

> Stefan Bellon wrote:
> 
> >       Padded_Data : String (1 .. Padded_Length) := (others =>
> > ASCII.NUL); --  Padded input data.
> [...]
> >    begin
> >       Padded_Data (1 .. Data'Length) := Data;
> >       --  Initialize data into padded-data (can't be done with
> > aggregate --  in elaboration part, sadly).
> 
> Why?  I may have missed something obvious, but I would have thought
> that
> 
>    Padded_Data : String (1 .. Padded_Length) := Data & (others =>
> ASCII.NUL);
> 
> would work fine.

This results in:

   error: "others" choice not allowed here

> > However it looks like this solution has a problem with endianness,
> > in a way that the wrong 6 bits of the Bytes are used in the
> > conversion.
> 
> :-(
> 
> > Is there an easy way to fix this (as I think the rest would be
> > pretty neat) or is this way of trying to do it, doomed to fail
> > anyway?
> 
> Is it a problem that section 13.5.3 (Bit Ordering) can handle?

I hoped for this as well, but it looks like the attribute Bit_Order is
only defined for record types. This is what 13.5.3 says and indeed GNAT
refuses to accept a 'Bit_Order on Six_Bits or the array thereof.

-- 
Stefan Bellon



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-15 14:54   ` Base64-Encoding Stefan Bellon
@ 2007-10-15 15:14     ` Jacob Sparre Andersen
  2007-10-15 15:37       ` Base64-Encoding Robert A Duff
  2007-10-15 15:40     ` Base64-Encoding Jean-Pierre Rosen
  1 sibling, 1 reply; 17+ messages in thread
From: Jacob Sparre Andersen @ 2007-10-15 15:14 UTC (permalink / raw)


Stefan Bellon wrote:
> On Mon, 15 Oct, Jacob Sparre Andersen wrote:

>>    Padded_Data : String (1 .. Padded_Length) := Data & (others =>
>> ASCII.NUL);
>> 
>> would work fine.
>
> This results in:
>
>    error: "others" choice not allowed here

I can't figure out why, but here's something which does work:

      Padded_Data : String (1 .. Padded_Length) := 
                      Data & (Data'Length + 1 .. Padded_Length => ASCII.NUL);

> I hoped for this as well, but it looks like the attribute Bit_Order is
> only defined for record types. This is what 13.5.3 says and indeed GNAT
> refuses to accept a 'Bit_Order on Six_Bits or the array thereof.

Doesn't that simply mean that you have to make "Base64_Data" an array
of Base64_Block, where Base64_Block is declared like this:

   type Base64_Block is
      record
         A, B, C, D : Six_Bits;
      end record;

This way you will be allowed bit ordering on the Base64_Block, which
hopefully will solve your problem.

Greetings,

Jacob
-- 
Adlai Stevenson said it all when, at an event during the
1956 Presidential campaign, a woman shouted, "You have the
vote of every thinking person!" Stevenson shouted back,
"That's not enough, madam, we need a majority!"



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-15 15:14     ` Base64-Encoding Jacob Sparre Andersen
@ 2007-10-15 15:37       ` Robert A Duff
  0 siblings, 0 replies; 17+ messages in thread
From: Robert A Duff @ 2007-10-15 15:37 UTC (permalink / raw)


Jacob Sparre Andersen <sparre@nbi.dk> writes:

> Stefan Bellon wrote:
>> On Mon, 15 Oct, Jacob Sparre Andersen wrote:
>
>>>    Padded_Data : String (1 .. Padded_Length) := Data & (others =>
>>> ASCII.NUL);
>>> 
>>> would work fine.
>>
>> This results in:
>>
>>    error: "others" choice not allowed here
>
> I can't figure out why, ...

Because Ada allows "others" only when the context determines the bounds
of the array:

    X : String (1..10) := (others => '*'); -- OK, bounds of others come from X
    Y : String := (1..10 => '*'); -- OK, bounds of Y come from aggregate
    Z : String := (others => '*'); -- Illegal (what is Z'Length?)

The right-hand parameter of the "&" function is of subtype String,
which is unconstrained, so you can't pass an others-aggregate to it.

I suppose the language COULD have been defined to allow it,
by special-casing the predefined "&".  Allow one (but not both)
parameters of "&" to have others, but only if the "&" operator
appears in an appropriate context:

    A : String := "Hello";
    function F(X : Integer) return String;
    B : String (1..100) := A & (others => '*') & F(123); -- Illegal.

Requiring the generated code to calculate the bounds
of others as B'First + A'Length .. B'Last - <result-of-F>'Length.
Yuck -- that works for "&", but not for user-defined functions.
Sounds like a complicated rule, for little benefit, since as you point
out, it's not that hard to calculate the bounds explicitly:

>... but here's something which does work:
>
>       Padded_Data : String (1 .. Padded_Length) := 
>                       Data & (Data'Length + 1 .. Padded_Length => ASCII.NUL);

- Bob



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-15 14:54   ` Base64-Encoding Stefan Bellon
  2007-10-15 15:14     ` Base64-Encoding Jacob Sparre Andersen
@ 2007-10-15 15:40     ` Jean-Pierre Rosen
  2007-10-15 16:39       ` Base64-Encoding Stefan Bellon
  1 sibling, 1 reply; 17+ messages in thread
From: Jean-Pierre Rosen @ 2007-10-15 15:40 UTC (permalink / raw)


Stefan Bellon a �crit :
> On Mon, 15 Oct, Jacob Sparre Andersen wrote:
> 
>> Stefan Bellon wrote:
>>
>>>       Padded_Data : String (1 .. Padded_Length) := (others =>
>>> ASCII.NUL); --  Padded input data.
>> [...]
>>>    begin
>>>       Padded_Data (1 .. Data'Length) := Data;
>>>       --  Initialize data into padded-data (can't be done with
>>> aggregate --  in elaboration part, sadly).
>> Why?  I may have missed something obvious, but I would have thought
>> that
>>
>>    Padded_Data : String (1 .. Padded_Length) := Data & (others =>
>> ASCII.NUL);
>>
>> would work fine.
> 
> This results in:
> 
>    error: "others" choice not allowed here
How many elements are covered byt "others" cannot be determined in this 
context, but this should work:
    Padded_Data : String (1 .. Padded_Length)
       := Data & (Data'Length+1 .. Padded_Length => ASCII.NUL);

> I hoped for this as well, but it looks like the attribute Bit_Order is
> only defined for record types. This is what 13.5.3 says and indeed GNAT
> refuses to accept a 'Bit_Order on Six_Bits or the array thereof.

Bit_Order is about bit numbering, it has nothing to do with endianness

-- 
---------------------------------------------------------
            J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-15 15:40     ` Base64-Encoding Jean-Pierre Rosen
@ 2007-10-15 16:39       ` Stefan Bellon
  2007-10-16 10:42         ` Base64-Encoding Stephen Leake
  0 siblings, 1 reply; 17+ messages in thread
From: Stefan Bellon @ 2007-10-15 16:39 UTC (permalink / raw)


On Mon, 15 Oct, Jean-Pierre Rosen wrote:
> Stefan Bellon a écrit :

> > I hoped for this as well, but it looks like the attribute Bit_Order
> > is only defined for record types. This is what 13.5.3 says and
> > indeed GNAT refuses to accept a 'Bit_Order on Six_Bits or the array
> > thereof.
> 
> Bit_Order is about bit numbering, it has nothing to do with endianness

Ok, bad wording on my part. Let my try to explain what I mean.

The German Wikipedia page for Base64 has a nice coloured illustration:
http://de.wikipedia.org/wiki/Base64

My basic idea is to define an array of Six_Bits and "overlay" this at
the same address as the String with the usual 8-bit Character encoding.

Then iterate over the Six_Bits' array and use the values (which are mod
2**6) to index the Base64_Chars array and build the result buffer.

However, when the 1st Byte contains the value Character'Pos('0') = 48,
I hoped that the first Six_Bits element in the array contained the
first 6 bits and thus has a value of 48 / 4 = 12. But this is not the
case. It has the value 48 as well.

In the case of Character'Pos('A') = 65, the usual bit value is
2#01000001#, so I had assumed the first Six_Bits element had the value
16 and the second Six_Bits element had the value 16 as well (assuming
0-padding).

          Data(1)
           __65__
          /      \
          010000010000...
          010000010000
          \____/\____/
            16    16
          B64(1) B64(2)

But in fact, both Six_Bits elements have the value 1. The fact, that I
get 1 in both cases, leads me to the conclusion, that the
Six_Bits_Array overlays differently:

              Data(1)
               __65__
              /      \
       ...000001000001
          000001000001
          \____/\____/
             1     1
          B64(2) B64(1)

When I test this now with two consecutive bytes, I had expected to get:

          Data(1) Data(2)
           _129__  _126__
          /      \/      \
          100000010111111000...
          \____/\____/\____/
            32    23    56
         B64(1) B64(2) B64(3)

But what I am seeing is this:

B64(1..3) = (1, 58, 7) = (2#000001#, 2#111010#, 2#000111#)

But this only makes sense, if the bits are in complete reverse order:

             7     58      1
          000111 111010 000001

Therefore I assume that when overlaying the array of 6-bit elements
over an array of 8-bit elements, I have to specify some kind of bit
ordering, which however is not possible with 'Bit_Order.

What am I missing here?

-- 
Stefan Bellon



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-15 14:12 Base64-Encoding Stefan Bellon
  2007-10-15 14:46 ` Base64-Encoding Jacob Sparre Andersen
@ 2007-10-15 18:24 ` Adam Beneschan
  2007-10-19  2:43 ` Base64-Encoding anon
  2 siblings, 0 replies; 17+ messages in thread
From: Adam Beneschan @ 2007-10-15 18:24 UTC (permalink / raw)


On Oct 15, 7:12 am, Stefan Bellon <sbel...@sbellon.de> wrote:
> Hi all,
>
> I've been looking through the previous postings of the group and found
> two major threads where this topic has already been discussed. But the
> proposed solutions were all different to what I was thinking about. I
> have thought about the following:
>
> package body Base64 is
>
>    type Six_Bits is mod 2**6;
>    for Six_Bits'Size use 6;
>
>    type Six_Bits_Array is array (Natural range <>) of Six_Bits;
>    for Six_Bits_Array'Alignment use 1;  --  To overlay over String type.
>    for Six_Bits_Array'Component_Size use Six_Bits'Size;
>    pragma Pack (Six_Bits_Array);
>
>    Base64_Chars : constant array (Six_Bits) of Character :=
>      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
>
>    function Encode
>      (Data : in String)
>      return String
>    is
>       Padded_Length : constant Natural := ((Data'Length + 2) / 3) * 3;
>       --  Pad input data to 3-Byte boundary.
>
>       Base64_Length : constant Natural := Padded_Length / 3 * 4;
>       --  Number of six-bit tokens necessary (including padding).
>
>       Six_Bits_Length : constant Natural := (Data'Length * 4 + 2) / 3;
>       --  Number of six-bit tokens necessary (without padding).
>
>       Padded_Data : String (1 .. Padded_Length) := (others => ASCII.NUL);
>       --  Padded input data.
>
>       Base64_Data : Six_Bits_Array (1 .. Base64_Length);
>       for Base64_Data'Address use Padded_Data'Address;
>       --  Overlay array of six-bit tokens over the padded input data.
>
>       Result : String (1 .. Base64_Length) := (others => '=');
>       --  Output buffer, initialized with '=' tokens for unfilled
>       --  end-markers.
>    begin
>       Padded_Data (1 .. Data'Length) := Data;
>       --  Initialize data into padded-data (can't be done with aggregate
>       --  in elaboration part, sadly).
>
>       --  Do the actual encoding ...
>       for I in 1 .. Six_Bits_Length loop
>          Result (I) := Base64_Chars (Base64_Data (I));
>       end loop;
>
>       return Result;
>    end Encode;
>
> end Base64;
>
> However it looks like this solution has a problem with endianness, in a
> way that the wrong 6 bits of the Bytes are used in the conversion.
>
> Is there an easy way to fix this (as I think the rest would be pretty
> neat) or is this way of trying to do it, doomed to fail anyway?

I vote for "doomed"---if your intent is to write portable code.  The
problem is that Ada doesn't give you enough control over the
representation of an array to solve the problem the way you'd like
to.  You're hoping for a representation of an array of 6-bit integers,
such that the first array element is contained in the upper 6 bits of
the first byte, the second array element is such that the two high
bits of the element are the lower 2 bits of the first byte and the
remaning four bits are the lower 4 bits of the second byte, etc.  I
don't think there's a way in Ada to specify an array representation
that precisely.  From what I can tell, if it's more convenient for an
implementation to store the first element in the low-order bits of the
*third* byte (let's say it can load three bytes as an integer
containing four array elements and then perform register shift
instructions to get the desired element), it is free to do so and
there's no Ada-defined pragma or representation clause to prevent it
from doing so.

If it were me, I'd just do the shifting and masking operations
myself.  You may be able to get somewhere by defining a record
containing four 6-bit integers and taking up three bytes, and using a
record representation clause to specify the exact locations of those
four integers.  You'd probably even be able to do this in a way that's
endianness-independent---I haven't tried it.  Of course, you'd have to
perform your operation on the four components of those records
separately; you can't put them into an array.

                     -- Adam




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-15 16:39       ` Base64-Encoding Stefan Bellon
@ 2007-10-16 10:42         ` Stephen Leake
  2007-10-17 14:07           ` Base64-Encoding Stefan Bellon
  0 siblings, 1 reply; 17+ messages in thread
From: Stephen Leake @ 2007-10-16 10:42 UTC (permalink / raw)


Stefan Bellon <sbellon@sbellon.de> writes:

> Ok, bad wording on my part. Let my try to explain what I mean.
>
> The German Wikipedia page for Base64 has a nice coloured illustration:
> http://de.wikipedia.org/wiki/Base64

In English: http://en.wikipedia.org/wiki/Base64

Not quite the same illustration, but the same idea.

> My basic idea is to define an array of Six_Bits and "overlay" this at
> the same address as the String with the usual 8-bit Character encoding.

I think Adam is correct that this is non-portable.

The GNAT Ada compiler has special code for each case of packed arrays.
For Six_Bits_Array, see the package System.Pack_06 (in file
s-pack06.adb). It defines:

   for Cluster use record
      E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1;
      E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1;
      E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1;
      E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1;
      E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1;
      E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1;
      E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1;
      E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1;
   end record;

where Bits is 6. There is no Bit_Order pragma on this, so it is in
native bit order; apparently little-endian in your case (x86).

So Base64_Data (0) has bits 0 .. 5 of Data (0), Base64_Data (1) has
bits 6, 7 of Data (0) and bits 0 .. 3 of Data (1), etc. In effect, the
bytes in Data are reversed in groups of 6. Not easy to draw :(.

AdaCore does not implement Bit_Order for machine sizes greater than 1
(last I checked; a couple years ago). If they did, and applied
bit_order to this record, it would be endian-independent, and work the
way you expect. It would also break any current code, so they probably
never will. But you could at least code it yourself in a cleaner
endian-independent way. So ask them to!

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-16 10:42         ` Base64-Encoding Stephen Leake
@ 2007-10-17 14:07           ` Stefan Bellon
  2007-10-17 15:09             ` Base64-Encoding Adam Beneschan
  0 siblings, 1 reply; 17+ messages in thread
From: Stefan Bellon @ 2007-10-17 14:07 UTC (permalink / raw)


On Tue, 16 Oct, Stephen Leake wrote:

> Stefan Bellon <sbellon@sbellon.de> writes:

> > My basic idea is to define an array of Six_Bits and "overlay" this
> > at the same address as the String with the usual 8-bit Character
> > encoding.
> 
> I think Adam is correct that this is non-portable.

Thanks a lot to you (and Adam as well!) for your detailed and very
informative replies.

> AdaCore does not implement Bit_Order for machine sizes greater than 1
> (last I checked; a couple years ago). If they did, and applied
> bit_order to this record, it would be endian-independent, and work the
> way you expect. 

Yes, I am not forced to exactly do it this way. In fact, there have
been discussions in this group explaining how to do it in several other
ways. I was just wondering because my idea initially looked like such an
elegant way. ;-)

-- 
Stefan Bellon



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-17 14:07           ` Base64-Encoding Stefan Bellon
@ 2007-10-17 15:09             ` Adam Beneschan
  2007-10-17 18:15               ` Base64-Encoding Larry Kilgallen
  0 siblings, 1 reply; 17+ messages in thread
From: Adam Beneschan @ 2007-10-17 15:09 UTC (permalink / raw)


On Oct 17, 7:07 am, Stefan Bellon <sbel...@sbellon.de> wrote:

> Yes, I am not forced to exactly do it this way. In fact, there have
> been discussions in this group explaining how to do it in several other
> ways. I was just wondering because my idea initially looked like such an
> elegant way. ;-)

It does seem like it would have been nice, and maybe it could be
argued that some sort of standard representation clause or pragma
should be added to give more control over how packed array elements
are stored.  The problem is that it would have to work not only for
big- and little-endian machines, but also on machines that are not
byte-addressable---there are still a few of those around.

                            -- Adam




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-17 15:09             ` Base64-Encoding Adam Beneschan
@ 2007-10-17 18:15               ` Larry Kilgallen
  0 siblings, 0 replies; 17+ messages in thread
From: Larry Kilgallen @ 2007-10-17 18:15 UTC (permalink / raw)


In article <1192633784.534337.221490@e34g2000pro.googlegroups.com>,  Adam Beneschan <adam@irvine.com> writes:
> On Oct 17, 7:07 am, Stefan Bellon <sbel...@sbellon.de> wrote:
> 
>> Yes, I am not forced to exactly do it this way. In fact, there have
>> been discussions in this group explaining how to do it in several other
>> ways. I was just wondering because my idea initially looked like such an
>> elegant way. ;-)
> 
> It does seem like it would have been nice, and maybe it could be
> argued that some sort of standard representation clause or pragma
> should be added to give more control over how packed array elements
> are stored.  The problem is that it would have to work not only for
> big- and little-endian machines, but also on machines that are not
> byte-addressable---there are still a few of those around.

The value of a standardized pragma to solve a problem that is specific
to particular architectures is questionable.  In fact, it might be a
bad idea to have a standardized pragma since those porting to another
architecture might presume that no changes were required.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-15 14:12 Base64-Encoding Stefan Bellon
  2007-10-15 14:46 ` Base64-Encoding Jacob Sparre Andersen
  2007-10-15 18:24 ` Base64-Encoding Adam Beneschan
@ 2007-10-19  2:43 ` anon
  2007-10-19  4:33   ` Base64-Encoding anon
  2007-10-19  6:59   ` Base64-Encoding Stefan Bellon
  2 siblings, 2 replies; 17+ messages in thread
From: anon @ 2007-10-19  2:43 UTC (permalink / raw)


with Interfaces ;
use  Interfaces ;
with System ;
use  System ;
with Ada.Unchecked_Conversion ;

package b64 is

  --
  -- Uses the system default on endian
  --

  type Six_Bits is new Integer range mod 2**6 ; -- or use 0 .. 63 ; 


  --
  -- base64_descriptor is a record that insures the endian is set 
  -- by the program ( in this case "little-endian format" ) in 
  -- architectures that have switchable endianness.
  -- Such as ARM, PowerPC (but not the PPC970/G5), DEC Alpha, SPARC V9, 
  -- MIPS, PA-RISC and IA64 
  --
  type base64_descriptor is record
                              Unused : Unsigned_8 range 0..3 ;
                              Bit_5  : Unsigned_8 range 0..1 ;
                              Bit_4  : Unsigned_8 range 0..1 ;
                              Bit_3  : Unsigned_8 range 0..1 ;
                              Bit_2  : Unsigned_8 range 0..1 ;
                              Bit_1  : Unsigned_8 range 0..1 ;
                              Bit_0  : Unsigned_8 range 0..1 ;
                            end record ;
  --
  -- set bit order
  --
  for base64_descriptor use record
                              Unused at 0 range 6..7 ;
                              Bit_5  at 0 range 5..5 ;
                              Bit_4  at 0 range 4..4 ;
                              Bit_3  at 0 range 3..3 ;
                              Bit_2  at 0 range 2..2 ;
                              Bit_1  at 0 range 1..1 ;
                              Bit_0  at 0 range 0..0 ;
                            end record ;

  --
  -- or you could use the following statement which 
  -- forces endian to little-endian format
  --
  for base64_descriptor'Bit_Order use Low_Order_First ;

  --
  -- insure 1 byte usage for base64_descriptor ;
  --
  pragma pack ( base64_descriptor ) ; 



  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 ) ;


end ;

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.


In <20071015161229.3f439230@cube.tz.axivion.com>, Stefan Bellon <sbellon@sbellon.de> writes:
>Hi all,
>
>I've been looking through the previous postings of the group and found
>two major threads where this topic has already been discussed. But the
>proposed solutions were all different to what I was thinking about. I
>have thought about the following:
>
>
>package body Base64 is
>
>   type Six_Bits is mod 2**6;
>   for Six_Bits'Size use 6;
>
>   type Six_Bits_Array is array (Natural range <>) of Six_Bits;
>   for Six_Bits_Array'Alignment use 1;  --  To overlay over String type.
>   for Six_Bits_Array'Component_Size use Six_Bits'Size;
>   pragma Pack (Six_Bits_Array);
>
>   Base64_Chars : constant array (Six_Bits) of Character :=
>     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
>
>   function Encode
>     (Data : in String)
>     return String
>   is
>      Padded_Length : constant Natural := ((Data'Length + 2) / 3) * 3;
>      --  Pad input data to 3-Byte boundary.
>
>      Base64_Length : constant Natural := Padded_Length / 3 * 4;
>      --  Number of six-bit tokens necessary (including padding).
>
>      Six_Bits_Length : constant Natural := (Data'Length * 4 + 2) / 3;
>      --  Number of six-bit tokens necessary (without padding).
>
>      Padded_Data : String (1 .. Padded_Length) := (others => ASCII.NUL);
>      --  Padded input data.
>
>      Base64_Data : Six_Bits_Array (1 .. Base64_Length);
>      for Base64_Data'Address use Padded_Data'Address;
>      --  Overlay array of six-bit tokens over the padded input data.
>
>      Result : String (1 .. Base64_Length) := (others => '=');
>      --  Output buffer, initialized with '=' tokens for unfilled
>      --  end-markers.
>   begin
>      Padded_Data (1 .. Data'Length) := Data;
>      --  Initialize data into padded-data (can't be done with aggregate
>      --  in elaboration part, sadly).
>
>      --  Do the actual encoding ...
>      for I in 1 .. Six_Bits_Length loop
>         Result (I) := Base64_Chars (Base64_Data (I));
>      end loop;
>
>      return Result;
>   end Encode;
>
>end Base64;
>
>
>However it looks like this solution has a problem with endianness, in a
>way that the wrong 6 bits of the Bytes are used in the conversion.
>
>Is there an easy way to fix this (as I think the rest would be pretty
>neat) or is this way of trying to do it, doomed to fail anyway?
>
>-- 
>Stefan Bellon




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-19  2:43 ` Base64-Encoding anon
@ 2007-10-19  4:33   ` anon
  2007-10-19  7:35     ` Base64-Encoding Jean-Pierre Rosen
  2007-10-19  6:59   ` Base64-Encoding Stefan Bellon
  1 sibling, 1 reply; 17+ messages in thread
From: anon @ 2007-10-19  4:33 UTC (permalink / raw)


that should say 

  type Six_Bits is new Integer mod 2**6 ; -- or use range 0 .. 63 ; 


In <eRURi.236438$ax1.167125@bgtnsc05-news.ops.worldnet.att.net>, anon@anon.org (anon) writes:
>with Interfaces ;
>use  Interfaces ;
>with System ;
>use  System ;
>with Ada.Unchecked_Conversion ;
>
>package b64 is
>
>  --
>  -- Uses the system default on endian
>  --
>
>  type Six_Bits is new Integer range mod 2**6 ; -- or use 0 .. 63 ; 
>
>
>  --
>  -- base64_descriptor is a record that insures the endian is set 
>  -- by the program ( in this case "little-endian format" ) in 
>  -- architectures that have switchable endianness.
>  -- Such as ARM, PowerPC (but not the PPC970/G5), DEC Alpha, SPARC V9, 
>  -- MIPS, PA-RISC and IA64 
>  --
>  type base64_descriptor is record
>                              Unused : Unsigned_8 range 0..3 ;
>                              Bit_5  : Unsigned_8 range 0..1 ;
>                              Bit_4  : Unsigned_8 range 0..1 ;
>                              Bit_3  : Unsigned_8 range 0..1 ;
>                              Bit_2  : Unsigned_8 range 0..1 ;
>                              Bit_1  : Unsigned_8 range 0..1 ;
>                              Bit_0  : Unsigned_8 range 0..1 ;
>                            end record ;
>  --
>  -- set bit order
>  --
>  for base64_descriptor use record
>                              Unused at 0 range 6..7 ;
>                              Bit_5  at 0 range 5..5 ;
>                              Bit_4  at 0 range 4..4 ;
>                              Bit_3  at 0 range 3..3 ;
>                              Bit_2  at 0 range 2..2 ;
>                              Bit_1  at 0 range 1..1 ;
>                              Bit_0  at 0 range 0..0 ;
>                            end record ;
>
>  --
>  -- or you could use the following statement which 
>  -- forces endian to little-endian format
>  --
>  for base64_descriptor'Bit_Order use Low_Order_First ;
>
>  --
>  -- insure 1 byte usage for base64_descriptor ;
>  --
>  pragma pack ( base64_descriptor ) ; 
>
>
>
>  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 ) ;
>
>
>end ;
>
>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.
>
>
>In <20071015161229.3f439230@cube.tz.axivion.com>, Stefan Bellon <sbellon@sbellon.de> writes:
>>Hi all,
>>
>>I've been looking through the previous postings of the group and found
>>two major threads where this topic has already been discussed. But the
>>proposed solutions were all different to what I was thinking about. I
>>have thought about the following:
>>
>>
>>package body Base64 is
>>
>>   type Six_Bits is mod 2**6;
>>   for Six_Bits'Size use 6;
>>
>>   type Six_Bits_Array is array (Natural range <>) of Six_Bits;
>>   for Six_Bits_Array'Alignment use 1;  --  To overlay over String type.
>>   for Six_Bits_Array'Component_Size use Six_Bits'Size;
>>   pragma Pack (Six_Bits_Array);
>>
>>   Base64_Chars : constant array (Six_Bits) of Character :=
>>     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
>>
>>   function Encode
>>     (Data : in String)
>>     return String
>>   is
>>      Padded_Length : constant Natural := ((Data'Length + 2) / 3) * 3;
>>      --  Pad input data to 3-Byte boundary.
>>
>>      Base64_Length : constant Natural := Padded_Length / 3 * 4;
>>      --  Number of six-bit tokens necessary (including padding).
>>
>>      Six_Bits_Length : constant Natural := (Data'Length * 4 + 2) / 3;
>>      --  Number of six-bit tokens necessary (without padding).
>>
>>      Padded_Data : String (1 .. Padded_Length) := (others => ASCII.NUL);
>>      --  Padded input data.
>>
>>      Base64_Data : Six_Bits_Array (1 .. Base64_Length);
>>      for Base64_Data'Address use Padded_Data'Address;
>>      --  Overlay array of six-bit tokens over the padded input data.
>>
>>      Result : String (1 .. Base64_Length) := (others => '=');
>>      --  Output buffer, initialized with '=' tokens for unfilled
>>      --  end-markers.
>>   begin
>>      Padded_Data (1 .. Data'Length) := Data;
>>      --  Initialize data into padded-data (can't be done with aggregate
>>      --  in elaboration part, sadly).
>>
>>      --  Do the actual encoding ...
>>      for I in 1 .. Six_Bits_Length loop
>>         Result (I) := Base64_Chars (Base64_Data (I));
>>      end loop;
>>
>>      return Result;
>>   end Encode;
>>
>>end Base64;
>>
>>
>>However it looks like this solution has a problem with endianness, in a
>>way that the wrong 6 bits of the Bytes are used in the conversion.
>>
>>Is there an easy way to fix this (as I think the rest would be pretty
>>neat) or is this way of trying to do it, doomed to fail anyway?
>>
>>-- 
>>Stefan Bellon
>




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-19  2:43 ` Base64-Encoding anon
  2007-10-19  4:33   ` Base64-Encoding anon
@ 2007-10-19  6:59   ` Stefan Bellon
  2007-10-19 19:40     ` Base64-Encoding anon
  1 sibling, 1 reply; 17+ messages in thread
From: Stefan Bellon @ 2007-10-19  6:59 UTC (permalink / raw)


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



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-19  4:33   ` Base64-Encoding anon
@ 2007-10-19  7:35     ` Jean-Pierre Rosen
  0 siblings, 0 replies; 17+ messages in thread
From: Jean-Pierre Rosen @ 2007-10-19  7:35 UTC (permalink / raw)


anon a �crit :
> that should say 
> 
>   type Six_Bits is new Integer mod 2**6 ; -- or use range 0 .. 63 ; 
> 
Missed again! Should be:
    type Six_Bits is mod 2**6;

Please get rid of references to Integer! They buy you nothing but trouble...

-- 
---------------------------------------------------------
            J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Base64-Encoding
  2007-10-19  6:59   ` Base64-Encoding Stefan Bellon
@ 2007-10-19 19:40     ` anon
  0 siblings, 0 replies; 17+ messages in thread
From: anon @ 2007-10-19 19:40 UTC (permalink / raw)


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




^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2007-10-19 19:40 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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     ` Base64-Encoding anon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox