Last active
July 8, 2021 21:55
-
-
Save zunda/91cd01227d6fb5980cb0 to your computer and use it in GitHub Desktop.
りっぱになったふっかつのじゅもん生成器
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/usr/bin/ruby | |
require "securerandom" | |
class Integer | |
def stringify(chars, edge_chars, min_digits = nil) | |
if self < 0 | |
raise ArgumentError, "Can not stringify negative numbers" | |
end | |
unless (edge_chars - chars).empty? | |
raise ArgumentError, "Characters need to contain edge characters" | |
end | |
d = chars.size | |
e = edge_chars.size | |
x, c = self.divmod(e) | |
r = edge_chars[c].dup | |
i = 1 | |
while x >= e | |
x, c = x.divmod(d) | |
r << chars[c] | |
i += 1 | |
end | |
if x > 0 | |
x, c = x.divmod(e) | |
r << edge_chars[c] | |
i += 1 | |
end | |
if min_digits and i < min_digits | |
r << edge_chars[0]*(min_digits - i) | |
end | |
return r.reverse | |
end | |
end | |
if __FILE__ == $0 | |
require 'optparse' | |
default_length = 16 | |
cset = { | |
:Alphabet => ('A'..'Z').to_a + ('a'..'z').to_a, | |
:Numbers => ('0'..'9').to_a, | |
:Space => [' '], | |
:Printables => (32..126).map{|i| i.chr}, | |
:Hiragana_dot_bar => ('ぁ'..'ん').to_a + ['・', 'ー'], | |
} | |
c = [] | |
l = default_length | |
opt = OptionParser.new | |
opt.on('-a', 'include lower and upper case alphabet'){c += cset[:Alphabet]} | |
opt.on('-n', 'include 0 - 9'){c += cset[:Numbers]} | |
opt.on('-s', 'include space'){c += cset[:Space]} | |
opt.on('-p', 'include all printable characters (default)'){ | |
c += cset[:Printables] | |
} | |
opt.on('--hiragana-dot-bar', 'include hiragana, cdot, and bar'){ | |
c += cset[:Hiragana_dot_bar] | |
} | |
opt.on('-l LENGTH', "number of characters (default: #{default_length}"){|v| | |
l = Integer(v) | |
} | |
opt.on('--test', 'run tests'){ | |
require 'test/unit' | |
class TestStringify < Test::Unit::TestCase | |
def setup | |
@c = ('0'..'9').to_a | |
end | |
def test_normal | |
assert_equal '123', 123.stringify(@c, @c) | |
end | |
def test_negative | |
assert_raise ArgumentError do | |
-123.stringify(@c, @c) | |
end | |
end | |
def test_normal_with_len | |
assert_equal '0123', 123.stringify(@c, @c, 4) | |
assert_equal '123', 123.stringify(@c, @c, 1) | |
end | |
end | |
class TestStringifyWithSpace < Test::Unit::TestCase | |
def setup | |
@c = ['0', '1'] | |
@e = ['1'] | |
end | |
def test_normal | |
assert_equal '0', 0.stringify(@c, @c) | |
assert_equal '1', 1.stringify(@c, @c) | |
assert_equal '10', 2.stringify(@c, @c) | |
assert_equal '11', 3.stringify(@c, @c) | |
assert_equal '100', 4.stringify(@c, @c) | |
assert_equal '101', 5.stringify(@c, @c) | |
assert_equal '110', 6.stringify(@c, @c) | |
assert_equal '111', 7.stringify(@c, @c) | |
end | |
def test_trailng_edge | |
assert_equal '1', 0.stringify(@c, @e) | |
assert_equal '11', 1.stringify(@c, @e) | |
assert_equal '101', 2.stringify(@c, @e) | |
assert_equal '111', 3.stringify(@c, @e) | |
assert_equal '1001', 4.stringify(@c, @e) | |
assert_equal '1011', 5.stringify(@c, @e) | |
assert_equal '1101', 6.stringify(@c, @e) | |
assert_equal '1111', 7.stringify(@c, @e) | |
end | |
def test_leading_edge | |
assert_equal '1111', 0.stringify(@c, @e, 4) | |
assert_equal '1111', 1.stringify(@c, @e, 4) | |
assert_equal '1101', 2.stringify(@c, @e, 4) | |
assert_equal '1111', 3.stringify(@c, @e, 4) | |
assert_equal '1001', 4.stringify(@c, @e, 4) | |
assert_equal '1011', 5.stringify(@c, @e, 4) | |
assert_equal '1101', 6.stringify(@c, @e, 4) | |
assert_equal '1111', 7.stringify(@c, @e, 4) | |
end | |
def test_edge_more_than_normal | |
assert_raise ArgumentError do | |
123.stringify(@e, @c) | |
end | |
end | |
end | |
r = Test::Unit::AutoRunner.run | |
exit r | |
} | |
opt.parse!(ARGV) | |
c += cset[:Printables] if c.empty? or c == cset[:Space] | |
c.uniq! | |
e = c.reject{|x| x =~ /[[:space:]]/} | |
n = e.size**[2, l].min | |
n *= c.size**(l - 2) if l > 2 | |
if n <= 0 | |
raise RuntimeError, "Not enough non-space character candidates" | |
end | |
puts SecureRandom.rand(n).stringify(c, e, l) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment