2008-12-21 17 views
5

tengo matriz de bytes como entrada. Me gustaría convertir esa matriz a una cadena que contenga una representación hexadecimal de los valores de la matriz. Esto es F # Código:f # byte [] -> hexagonal -> conversión de cadenas

let ByteToHex bytes = 
    bytes 
    |> Array.map (fun (x : byte) -> String.Format("{0:X2}", x)) 

let ConcatArray stringArray = String.Join(null, (ByteToHex stringArray)) 

Esto produce resultados que necesito, pero me gustaría hacerlo más compacto de modo que tenga una sola función. No pude encontrar la función que concat la representación de cadena de cada byte al final de ByteToHex.
me trataron Array.concat, concat_map, probé con las listas, pero lo mejor que pude conseguir es matriz o lista de cadenas.

Preguntas:

  1. Lo que sería más simple, la forma más elegante de hacer esto?
  2. ¿Existe construir el formato de cadenas en C# para que pueda reemplazar String.Format del conjunto del sistema?

Ejemplo de entrada: [| 0x24uy; 0xA1uy; 0x00uy; 0x1Cuy |] debería producir la cadena "24A1001C"

Respuesta

5

No hay nada inherentemente malo con tu ejemplo. Si desea bajarlo a una sola expresión, utilice el método String.contcat.

let ByteToHex bytes = 
    bytes 
    |> Array.map (fun (x : byte) -> System.String.Format("{0:X2}", x)) 
    |> String.concat System.String.Empty 

Bajo el capó, String.concat se acaba de poner en string.join. Sin embargo, es posible que haya que modificar ligeramente su código porque, según la muestra, importa el sistema. Esto puede crear un conflicto de resolución de nombre entre F # String y System.String.

+0

Perfecto. Intenté con String.Concat, pero no agregué el argumento "System.String.Empty". – zendar

-1

Para ser honesto, eso no se ve terrible (aunque también tengo muy poca experiencia F #). ¿F # ofrece una manera fácil de iterar (foreach)? Si se trataba de C#, podría usar algo como (donde raw es un argumento byte[]):

 StringBuilder sb = new StringBuilder(); 
     foreach (byte b in raw) { 
      sb.Append(b.ToString("x2")); 
     } 
     return sb.ToString() 

Me pregunto cómo se traduce a F # ...

+0

Jeje, puedo wite de esa manera en Fa #, pero consulte esta presentación por Luca boloñesa http://channel9.msdn.com/pdc2008/TL11/ En primeros minutos no hay explicación sobre la diferencia entre el imperativo y la programación declarativa y el ejemplo se trata de iteradores. – zendar

+0

Bastante justo. Buscaré una mejor respuesta, entonces. Podría hacer algo de F # ;-p –

0

se ve bien para mí. Solo para señalar otra, en mi opinión, una función muy útil en el módulo Printf, echa un vistazo a ksprintf. Pasa el resultado de una cadena formateada a una función de su elección (en este caso, la función de identidad).

val ksprintf : (string -> 'd) -> StringFormat<'a,'d> -> 'a 
    sprintf, but call the given 'final' function to generate the result. 
1

Aquí hay otra respuesta:

let hashFormat (h : byte[]) = 
    let sb = StringBuilder(h.Length * 2) 
    let rec hashFormat' = function 
    | _ as currIndex when currIndex = h.Length -> sb.ToString() 
    | _ as currIndex -> 
     sb.AppendFormat("{0:X2}", h.[currIndex]) |> ignore 
     hashFormat' (currIndex + 1) 
    hashFormat' 0 

La ventaja de esto es que es recursiva de cola y que pre-asigna la cantidad exacta de espacio en el constructor de cadena como se requiere para convertir la matriz de bytes a una cadena hexagonal.

Para el contexto, lo tengo en este módulo:

module EncodingUtils 

open System 
open System.Text 
open System.Security.Cryptography 
open Newtonsoft.Json 

let private hmacmd5 = new HMACMD5() 
let private encoding = System.Text.Encoding.UTF8 
let private enc (str : string) = encoding.GetBytes str 
let private json o = JsonConvert.SerializeObject o 
let md5 a = a |> (json >> enc >> hmacmd5.ComputeHash >> hashFormat) 

Significado puedo pasar MD5 cualquier objeto y volver JSON un hash de la misma.

2

Si desea transformar y acumular en un solo paso, fold es su respuesta. sprintf es la función de formato de cadena F #.

let ByteToHex = Array.fold (fun state x-> state + sprintf "%02X" x) "" 
+1

esta es la forma más f # -py de resolverlo – albertjan

Cuestiones relacionadas