使用 ruby 生成一系列特殊字符

Generate a range of special characters with ruby

我目前对 ruby 很陌生,但我来自 PHP 背景,必须说我喜欢 ruby、 很多。这是一种非常好的语言,社区很严格但很有帮助。

今天我在查看 Whosebug,并检查了我的 中的一个问题,使用 PHP 生成随机字符串。我实际上为此编写了一个脚本,所以我想,为什么不分享它呢!

此脚本有一些修饰符,允许您选择是否要包含以下集合

  1. 小写 a-z
  2. [1] + 大写 a-z
  3. [1, 2] + 数字
  4. [1, 2, 3] + 特殊字符
  5. [1, 2, 3, 4] + 一些疯狂的巫毒角色

所以在这个 PHP 脚本中,我将每个集合物理地键入到一个数组中,例如:

$charSubSets = array(
    'abcdefghijklmnopqrstuvwxyz',
    'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
    '0123456789',
    '!@#$%^&*()_+{}|:">?<[]\\';,.`~',
    'µñ©æáßðøäåé®þüúíóö'
);

这基本上是我能够在那里定义复杂性的方式。

现在这看起来不错,即使在代码中也是如此,但是 ruby 有 ranges 并且范围对我来说是新的和闪亮的东西所以我想在今天晚些时候构建一个随机字符串生成器只是为了获得更多的经验。

现在回答我的问题,我知道您可以在范围内执行以下操作,包括:

  1. 'a'..'z'
  2. 'A'..'Z'
  3. 0..9

etc.. 但是我在想,你能不能也做一个特殊字符的范围?比如,只有个特殊字符?如果 是可能的,你也能为疯狂的巫毒做同样的事情吗?

我问的原因是因为 中没有示例或 SO 上的任何内容对此进行了解释。

是的 - 这当然是可能的。 启动你的控制台,例如irbpry.

1。对于特殊字符:

('!'..'?').to_a
# => [
#     "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-",
#     ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":",
#     ";", "<", "=", ">", "?"
# ]

2。对于 'voodooh' 个字符:

('µ'..'ö').to_a
# => [
#     "µ", "¶", "·", "¸", "¹", "º", "»", "¼", "½", "¾", "¿", "À", "Á",
#     "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î",
#     "Ï", "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö"
# ]

这很容易尝试,如果我选择 ~ 而不是,结束特殊字符在键盘上的位置(和键的 kb 索引)定义了中间的字符一个 ? 最后看起来像这样:

('!'..'~').to_a
# => [
#     "`", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",",
#     "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
#     ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F",
#     "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
#     "T", "U", "V", "W", "X", "Y", "Z", "[", "\", "]", "^", "_", "a",
#     "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
#     "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{",
#     "|", "}", "~"
# ]

基本上如果字符 a65 并且 z90 那么中间的所有字符如 b66 将是包括在内,它的工作方式与您放入范围内的任何内容一样,因为在 ruby 中一切都是对象,您可以使用范围内的任何内容,只要它实现了文档所解释的某些方法!

编辑 (13-11-2015)

在我的控制台上做了一些尝试后,我找到了这个 "mimics" 给定 PHP 示例的解决方案,甚至可能完成了它。

def rng(length = 10, complexity = 4)
    subsets = [("a".."z"), ("A".."Z"), (0..9), ("!".."?"), ("µ".."ö")]
    chars = subsets[0..complexity].map { |subset| subset.to_a }.flatten
    # => [
    #     "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
    #     "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x",
    #     "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
    #     "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
    #     "W", "X", "Y", "Z", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "!", "\"",
    #     "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".",
    #     "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":",
    #     ";", "<", "=", ">", "?", "µ", "¶", "·", "¸", "¹", "º", "»",
    #     "¼", "½", "¾", "¿", "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç",
    #     "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò", "Ó",
    #     "Ô", "Õ", "Ö"
    #  ]
    chars.sample(length).join
end

现在调用 rng 将产生如下结果:

rng         # => "·boÇE»Ñ¼Á¸"  
rng(10, 2)  # => "nyLYAsxJi9"  
rng(20, 2)  # => "EOcQdjZa0t36xCN8TkoX"

编辑#2 (14-05-2020)

正如下面评论中指出的,我什至没有提供相关概念的文档link,在Ruby中这被称为Range并且可以找到here (2.5.0).

如果您需要特定版本的文档,请尝试使用谷歌搜索 ruby range [your ruby version]。您可以在终端中通过 运行 ruby -v 查看您的版本。快乐 rubying :D

所有日期均采用 dd-mm-yyyy 格式

  1. 查看从 Enumerable 获取的 Range#to_a。请注意,在 docs 的左侧,它表示 Range 包含 Enumerable,这意味着可以在 Ranges 上调用 Enumerable 中的方法。如果您在 class 中找不到方法,请查看文档所说的 包含哪些模块 并单击 link 以包含模块。

  2. 查看 Array#shuffle

  3. 查看 Array#join

  4. 查看Array#[],它将一个范围作为下标,因此您可以取一个随机字符数组的切片。

  5. 两个点的范围包括结尾。三点范围不包括结尾:

    p (1...5).to_a #=> [1, 2, 3, 4]

综合起来:

chars = (0..9).to_a + ('A'..'z').to_a + ('!'..'?').to_a

10.times do 
  puts chars.shuffle[0..5].join
end

--output:--
I(m,E.
%_;i(3
rb=_ef
kJrA9n
YA`e.K
89qCji
Ba1x3D
acp)=8
2paq3I
U0>Znm

(莎士比亚最终会出现在那里。)