human_codes 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest.txt +10 -0
- data/README.txt +68 -0
- data/Rakefile +26 -0
- data/VERSION +1 -0
- data/human_codes.gemspec +48 -0
- data/init.rb +1 -0
- data/lib/human_codes.rb +63 -0
- data/rails/init.rb +1 -0
- data/test/test_human_codes.rb +77 -0
- metadata +70 -0
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
= Human Codes
|
2
|
+
|
3
|
+
* http://github.com/JackDanger/human_codes
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Convert integers to short, human-scannable alphanumeric strings (skipping 'l', '1', 'o', '0', etc.) and back.
|
8
|
+
|
9
|
+
Unlike the code behind url shorteners, this supports case-insensitive conversion and
|
10
|
+
omits letters and numbers that are difficult to distinguish by sight (like 'l' and '1')
|
11
|
+
|
12
|
+
== SYNOPSIS:
|
13
|
+
|
14
|
+
# 45.human_code
|
15
|
+
# => '2E'
|
16
|
+
# 5234233.human_code
|
17
|
+
# '5ZRJT'
|
18
|
+
# 'AYH783XM3AJZ99'.human_code
|
19
|
+
# => 367212504123260337416
|
20
|
+
# 367212504123260337416.human_code
|
21
|
+
# => 'AYH783XM3AJZ99'
|
22
|
+
#
|
23
|
+
## strings that weren't generated by this library don't get converted
|
24
|
+
#
|
25
|
+
# "ajYz2".human_code
|
26
|
+
# => "ajyz2"
|
27
|
+
#
|
28
|
+
## But your users shouldn't have to use the shift key
|
29
|
+
#
|
30
|
+
# "AJYZ2".human_code
|
31
|
+
# => 10025953
|
32
|
+
# "ajYz2".human_code :fix_case => true
|
33
|
+
# => 10025953
|
34
|
+
|
35
|
+
|
36
|
+
== INSTALL:
|
37
|
+
|
38
|
+
* sudo gem install human_codes
|
39
|
+
|
40
|
+
== WHERE CREDIT IS DUE
|
41
|
+
|
42
|
+
This project was inspired by my and Mike Mondragon's alphadecimal, Shane Becker's
|
43
|
+
NewBase60, and busy retail workers everywhere who need to enter coupon codes.
|
44
|
+
|
45
|
+
== LICENSE:
|
46
|
+
|
47
|
+
(The MIT License)
|
48
|
+
|
49
|
+
Copyright (c) 2010 Jack Danger Canty
|
50
|
+
|
51
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
52
|
+
a copy of this software and associated documentation files (the
|
53
|
+
'Software'), to deal in the Software without restriction, including
|
54
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
55
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
56
|
+
permit persons to whom the Software is furnished to do so, subject to
|
57
|
+
the following conditions:
|
58
|
+
|
59
|
+
The above copyright notice and this permission notice shall be
|
60
|
+
included in all copies or substantial portions of the Software.
|
61
|
+
|
62
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
63
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
64
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
65
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
66
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
67
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
68
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gem|
|
4
|
+
gem.name = "human_codes"
|
5
|
+
gem.summary = %Q{Convert integers to human-readable compressed alphanumeric strings and back. Lets humans enter very long integers quickly.}
|
6
|
+
gem.description = %Q{Convert integers to human-readable compressed alphanumeric strings and back. Lets humans enter very long integers quickly. Uses base-32 compression of integers.}
|
7
|
+
gem.email = "rubygems@6brand.com"
|
8
|
+
gem.homepage = "http://github.com/JackDanger/human_codes"
|
9
|
+
gem.authors = ["Jack Danger Canty"]
|
10
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
11
|
+
end
|
12
|
+
Jeweler::GemcutterTasks.new
|
13
|
+
rescue LoadError
|
14
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
task :default => :test
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << '.'
|
24
|
+
test.pattern = 'test/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.1.0
|
data/human_codes.gemspec
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{human_codes}
|
8
|
+
s.version = "1.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jack Danger Canty"]
|
12
|
+
s.date = %q{2010-07-12}
|
13
|
+
s.description = %q{Convert integers to human-readable compressed alphanumeric strings and back. Lets humans enter very long integers quickly. Uses base-32 compression of integers.}
|
14
|
+
s.email = %q{rubygems@6brand.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.txt"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"Manifest.txt",
|
20
|
+
"README.txt",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"human_codes.gemspec",
|
24
|
+
"init.rb",
|
25
|
+
"lib/human_codes.rb",
|
26
|
+
"rails/init.rb",
|
27
|
+
"test/test_human_codes.rb"
|
28
|
+
]
|
29
|
+
s.homepage = %q{http://github.com/JackDanger/human_codes}
|
30
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
31
|
+
s.require_paths = ["lib"]
|
32
|
+
s.rubygems_version = %q{1.3.6}
|
33
|
+
s.summary = %q{Convert integers to human-readable compressed alphanumeric strings and back. Lets humans enter very long integers quickly.}
|
34
|
+
s.test_files = [
|
35
|
+
"test/test_human_codes.rb"
|
36
|
+
]
|
37
|
+
|
38
|
+
if s.respond_to? :specification_version then
|
39
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
40
|
+
s.specification_version = 3
|
41
|
+
|
42
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
43
|
+
else
|
44
|
+
end
|
45
|
+
else
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'alphadecimal'
|
data/lib/human_codes.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
module HumanCodes
|
2
|
+
SAFE_NUMBERS = '2','3','4','5','6','7','8','9'
|
3
|
+
SAFE_LETTERS = 'A','B','C','D','E','F','G','H','J','K','M','N','P','Q','R','S','T','U','V','W','X','Y','Z'
|
4
|
+
SAFE_BASE = SAFE_NUMBERS.size + SAFE_LETTERS.size
|
5
|
+
SAFE_CHARACTERS_AS_ASCII =
|
6
|
+
[SAFE_NUMBERS + SAFE_LETTERS].flatten.inject({}) do |hash, char|
|
7
|
+
hash[char[0]] = hash.size
|
8
|
+
hash
|
9
|
+
end
|
10
|
+
SAFE_CHARACTERS_AS_STRINGS = [
|
11
|
+
SAFE_NUMBERS.map {|char| char },
|
12
|
+
SAFE_LETTERS.map {|char| char }
|
13
|
+
].flatten
|
14
|
+
|
15
|
+
module Number
|
16
|
+
def human_code
|
17
|
+
return self if nil? || self <= 0
|
18
|
+
string = ""
|
19
|
+
value = self
|
20
|
+
until value == 0
|
21
|
+
mod = value % SAFE_BASE
|
22
|
+
string << SAFE_CHARACTERS_AS_STRINGS[mod]
|
23
|
+
value = value / SAFE_BASE
|
24
|
+
end
|
25
|
+
string.reverse
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module String
|
30
|
+
def human_code(options = {})
|
31
|
+
return upcase.human_code if options[:fix_case]
|
32
|
+
return self unless is_human_code?
|
33
|
+
val = 0
|
34
|
+
key = reverse
|
35
|
+
(0...key.size).each do |i|
|
36
|
+
char = key[i]
|
37
|
+
integer = SAFE_CHARACTERS_AS_ASCII[char]
|
38
|
+
val = val + (integer * (SAFE_BASE ** i))
|
39
|
+
end
|
40
|
+
val
|
41
|
+
end
|
42
|
+
|
43
|
+
def is_human_code?
|
44
|
+
return false if nil?
|
45
|
+
string = self.dup
|
46
|
+
return false if string.length <= 0
|
47
|
+
(0...string.size).each do |i|
|
48
|
+
return false unless SAFE_CHARACTERS_AS_ASCII[string[i]]
|
49
|
+
end
|
50
|
+
true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class String
|
56
|
+
include HumanCodes::String
|
57
|
+
end
|
58
|
+
class Fixnum
|
59
|
+
include HumanCodes::Number
|
60
|
+
end
|
61
|
+
class Bignum
|
62
|
+
include HumanCodes::Number
|
63
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'alphadecimal'
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + "/../lib/human_codes"
|
3
|
+
|
4
|
+
class TestHumanCodes < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include HumanCodes
|
7
|
+
|
8
|
+
def test_fixnum_becomes_string
|
9
|
+
assert_kind_of String, 45.human_code
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_bignum_becomes_string
|
13
|
+
assert_kind_of String, 231087934571049032.human_code
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_string_becomes_bignum
|
17
|
+
assert_kind_of Bignum, 'AHEATZZTAJBC43JZY'.human_code
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_string_allows_optional_auto_upcasing
|
21
|
+
assert_kind_of Fixnum, 'abh56ak'.human_code(:fix_case => true)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_string_does_not_automatically_upcase
|
25
|
+
assert_kind_of String, 'abh56ak'.human_code
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_string_becomes_fixnum
|
29
|
+
assert_kind_of Fixnum, 'J'.human_code
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_invalid_string_returns_self
|
33
|
+
string = 'Whoah there!'
|
34
|
+
assert_equal string, string.human_code
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_identities
|
38
|
+
[123, 90000008, 733, '12331', 'abYzj', '0', 'A', 'z',
|
39
|
+
79823898923232, 'ZZZZZZZZZZZZZZZZZZZ', 'Yz82J3Ng5Nj9M1',
|
40
|
+
'!!!', '@$%!^', 'abc ', 'HP', 4, 'ǟ'].each do |object|
|
41
|
+
assert_equal object, object.human_code.human_code
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_only_human_scannable_characters_should_validate
|
46
|
+
alphabet = ['2','3','4','5','6','7','8','9',
|
47
|
+
'A','B','C','D','E','F','G','H','J','K','M',
|
48
|
+
'N','P','Q','R','S','T','U','V','W','X','Y','Z'].map {|char| char[0] }
|
49
|
+
(0..255).each do |i|
|
50
|
+
case
|
51
|
+
when alphabet.include?(i)
|
52
|
+
assert i.chr.is_human_code?, "char #{i} is not valid as string #{i.chr}"
|
53
|
+
else
|
54
|
+
assert !i.chr.is_human_code?, "char #{i} is valid as string #{i.chr}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_edge_62_to_the_0_convertions_should_be_valid
|
60
|
+
(0...62).each do |i|
|
61
|
+
encode = i.human_code
|
62
|
+
decode = encode.human_code
|
63
|
+
assert_equal i, decode, "integer #{i} was encoded as #{encode} and was decoded to #{decode}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_edge_62_to_the_n_convertions_should_be_valid
|
68
|
+
(0...3).each do |p|
|
69
|
+
n = 62 ** p
|
70
|
+
(0...62).each do |i|
|
71
|
+
encode = (i+n).human_code
|
72
|
+
decode = encode.human_code
|
73
|
+
assert_equal i+n, decode, "interger #{i+n} was encoded as #{encode} and was decoded to #{decode}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: human_codes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 1.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Jack Danger Canty
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-12 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Convert integers to human-readable compressed alphanumeric strings and back. Lets humans enter very long integers quickly. Uses base-32 compression of integers.
|
22
|
+
email: rubygems@6brand.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README.txt
|
29
|
+
files:
|
30
|
+
- Manifest.txt
|
31
|
+
- README.txt
|
32
|
+
- Rakefile
|
33
|
+
- VERSION
|
34
|
+
- human_codes.gemspec
|
35
|
+
- init.rb
|
36
|
+
- lib/human_codes.rb
|
37
|
+
- rails/init.rb
|
38
|
+
- test/test_human_codes.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/JackDanger/human_codes
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --charset=UTF-8
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.3.6
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: Convert integers to human-readable compressed alphanumeric strings and back. Lets humans enter very long integers quickly.
|
69
|
+
test_files:
|
70
|
+
- test/test_human_codes.rb
|