Re: Base64-Encoding



On Oct 15, 7:12 am, Stefan Bellon <sbel...@xxxxxxxxxx> 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

.



Relevant Pages

  • Re: Optimization problem
    ... public class Point { ... Points are gathered in shapes and these form a stage. ... And somewhere else I have a global array: double, where N is the number of points, known in advance. ... So, a packed representation is ~20% faster than a naive representation, whilst the N x 3 representation is actually slower. ...
    (comp.lang.java.programmer)
  • Re: [opensuse] Processing large wads of data with SuSE
    ... what information is held at each array address? ... the visual representation. ... status of adjoining cells. ... Now I am not very sure that FORTRAN even in its modern form is really up ...
    (SuSE)
  • Re: what is the best datatype for..
    ... array that will be scanned searching for the index value, ... It also won't be flexible if the input data changes for any reason, since the implementation itself is so dependent on the input data. ... Calling the dictionary solution "inefficient" is just plain dumb; it might not be quite as fast as a straight array lookup, but it's not like it's a _slow_ design. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Beginner Programmer needs help
    ... >> which reliably gets input data. ... Doing user input in a 'foolproof' way is ... question is what state to leave the array in after such an ESC-press ...
    (comp.lang.cpp)
  • Re: Bugs at my web site
    ... "7.2.1.1.1 Array Element Successor Function and Value of a Subscript. ...
    (comp.lang.fortran)