F #: преобразование строки в массив байтов - PullRequest
6 голосов
/ 22 июля 2009

Я пишу простую утилиту шифрования / дешифрования rc4 в качестве первого проекта. Я застрял при попытке преобразовать данную строку в массив байтов, который затем может быть обработан основным алгоритмом. Как конвертировать строку в массив байтов в функционале f #?

//From another thread
let private replace find (repl : string) (str : string) = str.Replace(find, repl)

//let private algorithm bytes = blah blah blah

let Encrypt (decrypted : string) =
    decrypted.Chars
    |> Array.map(fun c -> byte.Parse(c)) // This line is clearly not working
    // |> algorithm
    |> BitConverter.ToString
    |> replace "-" ""

К вашему сведению в C # это выглядит так:

    public static string Encrypt(string decrypted)
    {
        byte[] bytes = new byte[decrypted.Length];

        for (int i = 0; i < decrypted.Length; ++i)
            bytes[i] = (byte)decrypted[i];

        Algorithm(ref bytes);

        return BitConverter.ToString(bytes).Replace("-", "").ToLower();
    }

Ответы [ 3 ]

10 голосов
/ 22 июля 2009

Несмотря на то, что вы могли бы написать собственную функцию для выполнения этой работы, лучше придерживаться встроенных методов .NET:

Строка в байтах:

System.Text.Encoding.ASCII.GetBytes("hello world!")

Байт в строку:

System.Text.Encoding.ASCII.GetString([|104uy; 101uy; 108uy; 108uy;
            111uy; 32uy; 119uy; 111uy; 114uy; 108uy; 100uy; 33uy|])
2 голосов
/ 22 июля 2009

По запросу Gradbot окончательный код выглядит так:

1) Мне не нравится приведение к байту

2) Функция основного алгоритма выглядит очень неработоспособной

Конструктивная критика приветствуется.

Rc4.fs

#light

open System
open MiscUtils
open StringUtils

let private key = "Mykey"B
let private byteMask = 0xff
let private byteMax  = byteMask

let private algorithm (bytes : byte[]) =
    let mutable j = 0
    let mutable i = 0
    let mutable s = [| for c in 0 .. byteMax -> (byte) c |]

    for i in 0 .. byteMax do
        j <- (j + (int) (s.[i] + key.[i % key.GetLength(0)])) &&& byteMask
        Swap (&s.[i]) (&s.[j])

    i <- 0
    j <- 0
    for x in 0 .. bytes.Length - 1 do
        i <- (i + 1) &&& byteMask
        j <- (j + (int) s.[i]) &&& byteMask
        Swap (&s.[i]) (&s.[j])
        let mutable t = (int)(s.[i] + s.[j]) &&& byteMask
        bytes.[x] <- bytes.[x] ^^^ s.[t]

    bytes

let Encrypt (decrypted : string) =
    Text.Encoding.ASCII.GetBytes decrypted
    |> algorithm
    |> BitConverter.ToString
    |> ToLower
    |> Replace "-" ""

let Decrypt (encrypted : string) =
    [| for i in 0 .. 2 .. encrypted.Length - 1 -> Convert.ToByte(encrypted.Substring(i, 2), 16) |]
    |> algorithm
    |> System.Text.Encoding.ASCII.GetString

StringUtils.Fs

#light

let Replace find (repl : string) (str : string) = str.Replace(find, repl)
let ToLower (str : string) = str.ToLower()

MiscUtils.fs

#light

let Swap (left : 'a byref) (right : 'a byref) =
    let temp = left
    left  <- right
    right <- temp
1 голос
/ 22 июля 2009

Вы могли бы сделать прямой перевод

let Encrypt(decrypted : string) =
    let bytes = Array.init decrypted.Length (fun i -> byte decrypted.[i])
    Algorithm(ref bytes)
    BitConverter.ToString(bytes).Replace("-", "").ToLower()
...