On Aug 6, 2006, at 11:29 PM, Meino Christian Cramer wrote:

>  My first idea was to define an Hash which maps an input range
>  to an index. To this index it is easy to add an offset. The
>  second step would be an array, which maps the new calculated index
>  (old index + offset) to the same range again, but this time
>  the range was "sorted" by sort{rand} st initialization time.
>
>  But when I do a "a=device.new", what should I return as an obejct
>  to the caller ??? TWO objects -- the hash AND the array ?

The whole point of wrapping something like this is in an object is  
that these are just internal details user code for the object never  
needs to worry about.  For example, users are going to call your code  
something like:

   dev   = Device.new( .. )
   after = dev.encryrpt(before)

All they know is that they are working with a Device.  They don't  
need to worry about Hashes and Arrays.

I recommend using a Hash internally in the object.  When a problem  
says "mapping" that usually means Hash.  You could build the  
interface to handle either a Hash or an Integer being passed to the  
constructor:

   class Device
     def initialize(mapping_or_offset)
       if mapping_or_offset.is_a? Hash
         @mapping = build_mapping_from_hash(mapping_or_offset)
       else # offset
         @mapping = build_mapping_from_integer(mapping_or_offset)
       end
     end

     def encrypt(bytes)
       # use @mapping here...
     end

     private

     def build_mapping_from_hash(hash)
       # ...
     end

     def build_mapping_from_integer(integer)
       # ...
     end
   end

Hope that gives you some fresh ideas.

James Edward Gray II