Browse files

implementing hex and base64 because ActiveSupport::SecureRandom is 's…

…urprising' e.g. hex(5).length == 10 / base64(5).length == 7
  • Loading branch information...
1 parent 099250a commit f76c8f4755fcef3c3186b1611d5b34b51ef82eae @grosser committed Oct 22, 2009
Showing with 49 additions and 14 deletions.
  1. +4 −0 README.markdown
  2. +11 −2 lib/readable_random.rb
  3. +34 −12 spec/readable_random_spec.rb
View
4 README.markdown
@@ -2,6 +2,7 @@ Readable string for coupon codes or auth tokens, something people can read/write
- more information density than hex -> shorter codes
- less confusion than base64 -> readable codes
+ - less 'stupid' then ActiveSupport::SecureRandom, e.g. hex(5).size == 5, not 10
Install
=======
@@ -19,6 +20,9 @@ Usage
end
end
+ ReadableRandom.hex(5) -> '12af4'
+ ReadableRandom.base64(5) -> 'at12k'
+
TODO
====
- prevent nasty words by not using vovels or a more clever tick...
View
13 lib/readable_random.rb
@@ -1,11 +1,12 @@
require 'openssl'
+require "base64"
class ReadableRandom
- EXCLUDE = %w[o O 0 1 l / = +]
+ NON_READABLE = %w[o O 0 1 l / = +]
def self.get(size)
try = random_string(size * 2)
- try = try.split('').reject{|x| EXCLUDE.include? x}.join('')
+ try = try.split('').reject{|x| NON_READABLE.include? x}.join('')
if try.length < size #too many excluded characters !?
get(size) #try once again...
@@ -14,6 +15,14 @@ def self.get(size)
end
end
+ def self.hex(size)
+ random_string(size).unpack("H*")[0][0...size]
+ end
+
+ def self.base64(size)
+ random_string(size)[0...size]
+ end
+
private
def self.random_string(size)
View
46 spec/readable_random_spec.rb
@@ -1,35 +1,57 @@
require 'spec/spec_helper'
describe ReadableRandom do
- describe :get do
- def set(size)
- set = []
- 100.times{ set << ReadableRandom.get(size) }
- set
- end
+ def set(method, size)
+ set = []
+ 100.times{ set << ReadableRandom.send(method, size) }
+ set
+ end
+ describe :get do
it "has the expected length" do
- set(7).map{|x|x.length}.uniq.should == [7]
+ set(:get, 7).map{|x|x.length}.uniq.should == [7]
end
it "is unique" do
- set = set(7)
+ set = set(:get, 7)
set.uniq.size.should == set.size
end
it "works for small numbers" do
- set(1).map{|x|x.length}.uniq.should == [1]
+ set(:get, 1).map{|x|x.length}.uniq.should == [1]
end
it "works for large numbers" do
- set(255).map{|x|x.length}.uniq.should == [255]
+ set(:get, 255).map{|x|x.length}.uniq.should == [255]
end
it "does not contain hard to read chars" do
- set = set(7)
- ReadableRandom::EXCLUDE.each do |ambiguouse_letter|
+ set = set(:get, 7)
+ ReadableRandom::NON_READABLE.each do |ambiguouse_letter|
(set * '').should_not include(ambiguouse_letter)
end
end
end
+
+ describe :hex do
+ it "has given length" do
+ set(:hex, 5).map{|x| x.length}.uniq.should == [5]
+ end
+
+ it "contains the hex chars" do
+ set(:hex, 5).map{|x| x.split('')}.flatten.uniq.sort.should == %w[0 1 2 3 4 5 6 7 8 9 a b c d e f]
+ end
+ end
+
+ describe :base64 do
+ it "has given length" do
+ set(:base64, 5).map{|x| x.length}.uniq.should == [5]
+ end
+
+ it "contains the base64 chars" do
+ base64_chars = (['+', '/'] + ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a)
+ set(:base64, 5).map{|x| x.split('')}.flatten.uniq.sort.should == base64_chars
+ end
+
+ end
end

0 comments on commit f76c8f4

Please sign in to comment.