如何从字节创建ruby uuid?

问题描述 投票:0回答:4

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不接受任何参数。

ruby uuid
4个回答
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
投票

有时开发过程涉及编写代码,而不仅仅是调用现有的库:

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"

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$标志来明确指定十六进制数字的顺序,例如%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"

......但是那时你也可以这样做:

positions = [ [ 3, 2, 1, 0 ], [ 5, 4 ], [ 7, 6 ], [ 8, 9 ], 10..15 ]
str = positions.map {|a| a.map {|n| "%02x" % arr[n] }.join }.join("-")
# => f29b616b-3424-57b6-43df-a3a607af7bdf

您可以在repl.it上看到所有这些操作:https://repl.it/@jrunning/FamousRewardingApplescript


-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。

© www.soinside.com 2019 - 2024. All rights reserved.