Dot-Net

F#:將字元串轉換為字節數組

  • July 23, 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();
   }

儘管您可以編寫自己的函式來完成這項工作,但最好還是堅持使用內置的 .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|])

根據 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

引用自:https://stackoverflow.com/questions/1161693