C # contiene un método para generar Guid a partir de bytes:

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ómo escribir código ruby que generará el mismo uuid que C #? El uuid definido en Ruby: SecureRandom doesn No acepte ningún parámetro.

0
jing 2 mar. 2018 a las 13:38

4 respuestas

La mejor respuesta

Otra forma de pelar un gato, simple y fácil de entender:

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
1
Harsh Gupta 3 mar. 2018 a las 02:30

Primera respuesta de aproximación:

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

Es casi seguro que hay una forma más limpia de hacerlo, pero esto le brinda algo con lo que trabajar. Utiliza inject para acumular las secciones de cadena de uuid generadas en una matriz, luego las une a la guid.

Cada bloque de la guía es un subconjunto de la matriz de bytes, aparentemente ordenado de lsb a msb.

-1
mcfinnigan 2 mar. 2018 a las 11:51

Aquí hay una manera, usando nada más que sprintf. No estoy seguro si lo amo o lo odio.

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"

Esto utiliza el indicador sprintf s $ para especificar explícitamente el orden de los dígitos hexadecimales, p. %4$02x significa "imprimir el cuarto octeto en los argumentos como dos dígitos hexadecimales".

Podríamos, por supuesto, generar la cadena de formato:

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"

... pero en ese momento también podrías hacer esto:

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

Puede ver todo esto en acción en repl.it: https://repl.it/@jrunning/FamousRewardingApplescript

2
Jordan Running 2 mar. 2018 a las 17:16

A veces, el proceso de desarrollo implica escribir código, no solo llamar a las bibliotecas existentes:

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"
3
Aleksei Matiushkin 2 mar. 2018 a las 11:51