(F#) 从 CryptoStream 读取所有字节的最平滑方法

发布于 2024-11-09 10:45:43 字数 441 浏览 2 评论 0原文

我正在研究使用 AesCryptoServiceProvider 解密二进制数据的过程。对于最后一步,检索解密的数据并将其作为字节数组返回,我目前正在使用以下实现:

let rec streamBytes (s : CryptoStream) (b : int) = seq {
    if b >= 0 then
        yield byte b
        yield! streamBytes s (s.ReadByte()) }
streamBytes cryptoStream (cryptoStream.ReadByte())
|> Seq.toArray

它可以工作,但对我来说感觉不“正确”。将 CryptoStream.ReadByte() 的结果作为参数传递给streamBytes(),然后检查该递归调用中的值似乎有点鲁布·戈德堡风格。有更好的方法吗?

I'm working on a procedure for decrypting binary data using AesCryptoServiceProvider. For the final step, retrieving the decrypted data and returning it as an array of bytes, I'm currently using the following implementation:

let rec streamBytes (s : CryptoStream) (b : int) = seq {
    if b >= 0 then
        yield byte b
        yield! streamBytes s (s.ReadByte()) }
streamBytes cryptoStream (cryptoStream.ReadByte())
|> Seq.toArray

It works, but it doesn't feel "correct" to me. Passing the result of CryptoStream.ReadByte() as an argument to streamBytes(), and then checking is value in that recursive call seems a bit Rube Goldberg-y. Is there a better way to be doing it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

━╋う一瞬間旳綻放 2024-11-16 10:45:43

逐字节排出流将会非常慢。

如果您有 .NET 4.0 那么最直接的方法是:

open System.IO

let readAllBytes (s : Stream) = 
    let ms = new MemoryStream()
    s.CopyTo(ms)
    ms.ToArray()

否则您需要手动重现 CopyTo 功能

let readAllBytes (s : Stream) =
    let ms = new MemoryStream()
    let buf = Array.zeroCreate 8192
    let rec impl () = 
        let read = s.Read(buf, 0, buf.Length) 
        if read > 0 then 
            ms.Write(buf, 0, read)
            impl ()
    impl ()

Draining stream byte by byte will be very slow.

if you have .NET 4.0 then the most straightforward way will be:

open System.IO

let readAllBytes (s : Stream) = 
    let ms = new MemoryStream()
    s.CopyTo(ms)
    ms.ToArray()

else you need to reproduce CopyTo functionality manually

let readAllBytes (s : Stream) =
    let ms = new MemoryStream()
    let buf = Array.zeroCreate 8192
    let rec impl () = 
        let read = s.Read(buf, 0, buf.Length) 
        if read > 0 then 
            ms.Write(buf, 0, read)
            impl ()
    impl ()
三生一梦 2024-11-16 10:45:43

是否有理由不使用 Read 而不是 ReadBytes?看起来这样会更直接一些。否则,你的解决方案对我来说看起来还不错 - API 的设计非常有限,因为你需要使用 ReadByte 的返回值来确定是否中断循环并决定执行什么操作值到输出。这是一种替代实现:

[| let currentByte = ref 0
   let moveNext() = 
       currentByte := cryptoStream.ReadByte()
       !currentByte >= 0
   while moveNext() do
       yield byte !currentByte |]

Is there a reason not to use Read instead of ReadBytes? It seems like that would be much more direct. Otherwise, your solution doesn't look too bad to me - the design of the API is pretty limiting, since you need to use the return value of ReadByte to determine whether to break your loop and to decide what value to output. Here's one alternative implementation:

[| let currentByte = ref 0
   let moveNext() = 
       currentByte := cryptoStream.ReadByte()
       !currentByte >= 0
   while moveNext() do
       yield byte !currentByte |]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文