C#包含从字节生成Guid的方法:
byte[] bytes = {107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223};
Guid guid = new Guid(bytes); // => {f29b616b-3424-57b6-43df-a3a607af7bdf}
如何编写将生成与C#相同的uuid的ruby代码? Ruby:SecureRandom中定义的uuid不接受任何参数。
答案 0 :(得分:3)
有时开发过程涉及编写代码,而不仅仅是调用现有的库:
bytes.each_with_object([]) do |b, acc|
acc << [] if acc.size == 0 ||
acc.size == 1 && acc.last.size == 4 ||
acc.size > 1 && acc.size < 5 && acc.last.size == 2
acc.last << b.to_s(16).rjust(2, '0')
end.map.with_index do |e, idx|
idx < 3 ? e.reverse : e
end.map(&:join).join('-')
#⇒ "f29b616b-3424-57b6-43df-a3a607af7bdf"
答案 1 :(得分:2)
这是一种方式,只使用sprintf
。我不确定我是喜欢它还是讨厌它。
arr = [107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223]
fmt = "%4$02x%3$02x%2$02x%1$02x-" \
"%6$02x%5$02x-%8$02x%7$02x-%9$02x%10$02x-" \
"%11$02x%12$02x%13$02x%14$x%15$x%16$x"
str = sprintf(fmt, *arr)
# => "f29b616b-3424-57b6-43df-a3a607af7bdf"
这使用sprintf
的{{1}}标志来明确指定十六进制数字的顺序,例如$
表示“将参数中的第四个八位字节打印为两个十六进制数字。”
我们当然可以生成格式字符串:
%4$02x
...但在那时你也可以这样做:
positions = [[4, 3, 2, 1], [6, 5], [8, 7], [9, 10], 11..16]
fmt = positions.map {|a| a.map {|d| "%#{d}$02x" }.join }.join("-")
# => "%4$02x%3$02x%2$02x%1$02x-%6$02x%5$02x-%8$02x%7$02x-%9$02x%10$02x-%11$02x%12$02x%13$02x%14$02x%15$02x%16$02x"
str = sprintf(fmt, *arr)
# => "f29b616b-3424-57b6-43df-a3a607af7bdf"
您可以在repl.it上看到所有这些操作:https://repl.it/@jrunning/FamousRewardingApplescript
答案 2 :(得分:1)
皮肤猫的另一种方法,简单易懂:
a = [107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223]
def _guid(ints, reverse=false)
hexes = ints.map { |b| b.to_s(16).rjust(2, '0') }
return hexes.reverse.join if reverse
hexes.join
end
def guid(ints)
'%s-%s-%s-%s-%s' % [
_guid(ints[0...4], true),
_guid(ints[4...6], true),
_guid(ints[6...8], true),
_guid(ints[8...10]),
_guid(ints[10..-1]),
]
end
puts guid a # => f29b616b-3424-57b6-43df-a3a607af7bdf
答案 3 :(得分:-1)
第一个近似答案:
a = [107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223]
ah = a.map{ |i| i.to_s(16) }
puts [4,2,2,2,6].inject([]) { |result, idx| result << ah.slice!(0, idx).reverse.join }.join("-")
f29b616b-3424-57b6-df43-df7baf7a6a3
=> nil
几乎可以肯定有一种更简洁的方法,但这可以让你有所作为。它使用inject将生成的uuid字符串部分累积到一个数组中,然后将它们连接到guid中。
guid的每个块都是字节数组的子数组,看起来像是命令lsb到msb。