string[x]
inRuby 1.8
给你一个Fixnum
(字符代码), in1.9
它给你一个single character string
.
Array#pack 将数组转换为二进制序列。要打包的“c*”模板将 Ruby 整数数组转换为 8 位有符号字流。
以下是解决方案,来自 Google Groups
1.
背景
>> %w(a b c).pack('*c')
TypeError: can't convert String into Integer
from (irb):1:in `pack'
from (irb):1
from /usr/bin/irb:12:in `<main>'
>> [1, 2, 3].pack('*c')
=> "\x01"
>> %w(a b c).map(&:ord).pack('*c')
=> "a"
解决方案
irb(main):001:0> length=nil
=> nil
irb(main):002:0> token_string ||= ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!$:*)
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$:*"
irb(main):003:0> (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.map(&:ord).pack("c*")
=> "rd!:!LcxU3ON57*t2s520v*zvvdflSNAgU6uq14SiD00VUDlm9:4:tJz5Ri5o"
irb(main):004:0>
2.
String's []
函数的返回类型Fixnum
在1.8
但String
在1.9
:
>JRUBY_OPTS=--1.9 ruby -e "puts 'a'[0].class"
String
>JRUBY_OPTS=--1.8 ruby -e "puts 'a'[0].class"
Fixnum
JRuby 1.7.x
默认表现得像Ruby 1.9.3
. 你需要设置JRUBY_OPTS
.
3.
尝试join
代替pack
irb(main):004:0> length=nil
=> nil
irb(main):005:0> token_string ||= ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!$:*)
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$:*"
irb(main):006:0> token = (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.join("c*")
=> "Fc*Dc*1c*6c*ac*Kc*Tc*Qc*Hc*jc*Ec*Kc*kc*zc*sc*3c*ic*hc*kc*wc**c*Wc*$c*Kc*Ic*Uc*Cc*bc*Pc*1c*!c*mc*Bc*lc*dc*ic*Dc*sc*Ac*Bc*nc*Kc*mc*Lc*oc*Zc*Xc*jc*6c*2c*Uc*ec*Yc*Dc*vc*Ic*Uc*5c*Zc*3c*o"
irb(main):007:0>
4.
如果您只是想制作一串 8 位干净的随机字符,您可能需要查看Random#bytes
类似Base64.encode64
.
5.
active_support/secure_random也有一个很好的 API 来处理这些事情