如何从字节创建 ruby uuid?
How to create ruby uuid from bytes?
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}
如何编写 ruby 生成与 C# 相同的 uuid 的代码? Ruby:SecureRandom中定义的uuid不接受任何参数。
有时开发过程涉及编写代码,而不仅仅是调用现有库:
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"
第一个近似答案:
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排序。
另一种给猫皮的方法,简单易懂:
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
这是一种方法,只使用 sprintf
。我不确定我是喜欢它还是讨厌它。
arr = [107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223]
fmt = "%4x%3x%2x%1x-" \
"%6x%5x-%8x%7x-%9x%10x-" \
"%11x%12x%13x%14$x%15$x%16$x"
str = sprintf(fmt, *arr)
# => "f29b616b-3424-57b6-43df-a3a607af7bdf"
这使用 sprintf
的 $
标志来明确指定十六进制数字的顺序,例如%4x
表示 "print the fourth octet in the arguments as two hex digits."
当然,我们可以生成格式字符串:
positions = [[4, 3, 2, 1], [6, 5], [8, 7], [9, 10], 11..16]
fmt = positions.map {|a| a.map {|d| "%#{d}x" }.join }.join("-")
# => "%4x%3x%2x%1x-%6x%5x-%8x%7x-%9x%10x-%11x%12x%13x%14x%15x%16x"
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
这可以通过将字节转换为十六进制字符串数组,将 -
插入正确的位置,然后加入数组来以非常简单的方式完成。
def to_uuid(bytes)
hex = bytes.map { |b| b.to_s(16).rjust(2, '0') }
[4, 7, 10, 13].inject(hex) { |hex, n| hex.insert(n, '-') }.join
end
to_uuid([107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223])
# => "6b619bf2-2434-b657-43df-a3a607af7bdf"
给定一个字节数组...
bytes = [107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223];
您可以将字节转换为十六进制,然后用前导 0
s...
填充生成的字符串
hex = bytes.map { |b| b.to_s(16).rjust(2, '0') }
# => ["6b", "61", "9b", "f2", "24", "34", "b6", "57", "43", "df", "a3", "a6", "07", "af", "7b", "df"]
然后在正确的地方插入连字符...
[4, 7, 10, 13].inject(hex) { |hex, n| hex.insert(n, '-') }
# => ["6b", "61", "9b", "f2", "-", "24", "34", "-", "b6", "57", "-", "43", "df", "-", "a3", "a6", "07", "af", "7b", "df"]
然后加入数组:
hex.join
# => "6b619bf2-2434-b657-43df-a3a607af7bdf"
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}
如何编写 ruby 生成与 C# 相同的 uuid 的代码? Ruby:SecureRandom中定义的uuid不接受任何参数。
有时开发过程涉及编写代码,而不仅仅是调用现有库:
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"
第一个近似答案:
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排序。
另一种给猫皮的方法,简单易懂:
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
这是一种方法,只使用 sprintf
。我不确定我是喜欢它还是讨厌它。
arr = [107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223]
fmt = "%4x%3x%2x%1x-" \
"%6x%5x-%8x%7x-%9x%10x-" \
"%11x%12x%13x%14$x%15$x%16$x"
str = sprintf(fmt, *arr)
# => "f29b616b-3424-57b6-43df-a3a607af7bdf"
这使用 sprintf
的 $
标志来明确指定十六进制数字的顺序,例如%4x
表示 "print the fourth octet in the arguments as two hex digits."
当然,我们可以生成格式字符串:
positions = [[4, 3, 2, 1], [6, 5], [8, 7], [9, 10], 11..16]
fmt = positions.map {|a| a.map {|d| "%#{d}x" }.join }.join("-")
# => "%4x%3x%2x%1x-%6x%5x-%8x%7x-%9x%10x-%11x%12x%13x%14x%15x%16x"
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
这可以通过将字节转换为十六进制字符串数组,将 -
插入正确的位置,然后加入数组来以非常简单的方式完成。
def to_uuid(bytes)
hex = bytes.map { |b| b.to_s(16).rjust(2, '0') }
[4, 7, 10, 13].inject(hex) { |hex, n| hex.insert(n, '-') }.join
end
to_uuid([107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223])
# => "6b619bf2-2434-b657-43df-a3a607af7bdf"
给定一个字节数组...
bytes = [107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223];
您可以将字节转换为十六进制,然后用前导 0
s...
hex = bytes.map { |b| b.to_s(16).rjust(2, '0') }
# => ["6b", "61", "9b", "f2", "24", "34", "b6", "57", "43", "df", "a3", "a6", "07", "af", "7b", "df"]
然后在正确的地方插入连字符...
[4, 7, 10, 13].inject(hex) { |hex, n| hex.insert(n, '-') }
# => ["6b", "61", "9b", "f2", "-", "24", "34", "-", "b6", "57", "-", "43", "df", "-", "a3", "a6", "07", "af", "7b", "df"]
然后加入数组:
hex.join
# => "6b619bf2-2434-b657-43df-a3a607af7bdf"