This is where the Hash construction magic takes place. The Hash:: class method will create a Hash object out of existing data. This method expects a number of arguments, and will alternate making each object a key or a value. For example, if you called Hash['a',10,'b',20], the keys would be 'a' with its value 10, and 'b' with its value 20. This is a shortcut used to generate hashes from existing data quickly.
This shortcut method doesn't take a single Array object. Instead, it takes the elements of the array as arguments to the method itself. To do this, the splat operator (a * character) is used. This will "splat" an Array object into individual parameters and pass them to the method.
To combine our two arrays (alpha and crypt), the zip method is used. The best way to explain zip is to just show it. Zip will "zip" two arrays into an array of arrays.
irb(main):001:0> a = ['a', 'b', 'c'] => ["a", "b", "c"] irb(main):002:0> b = [1, 2, 3] => [1, 2, 3] irb(main):003:0> a.zip(b) => [["a", 1], ["b", 2], ["c", 3]]
The arrays are zipped, concatenated to each other (so both lowercase and uppercase mappings are now in the same array of arrays), then flattened. Once flattened, all elements are now in a single, flat array. This array is splatted and passed to the hash construction method.