Skip to content

Instantly share code, notes, and snippets.

@rflechner
Created July 2, 2015 15:41
Show Gist options
  • Save rflechner/0b468b7adac4be463412 to your computer and use it in GitHub Desktop.
Save rflechner/0b468b7adac4be463412 to your computer and use it in GitHub Desktop.
RC4 stream encoding and decoding (bad performances)
open System
open System.Text
open System.IO
open System.Diagnostics
let mutable lastPercent = 0L
let computeRc4 (password:string) (content:Stream) (output:Stream) =
let swap (arr:byte array) (i:int) (j:int) =
let t = arr.[j]
arr.[j] <- arr.[i]
arr.[i] <- t
let keySchedule (password:string) =
let key = password |> Encoding.ASCII.GetBytes
let nums = [|0uy..255uy|]
let mutable j = 0
for i in [0..255] do
let t = (j + (int nums.[i]) + (key.[i % key.Length] |> int)) |> int
j <- t % 256
swap nums i j
nums
let rec compute (data:BinaryReader) (key:byte array) (i:int) (j:int) (writer:BinaryWriter) (n:int64) =
if n % 100L = 0L then
let percent = n * 100L / data.BaseStream.Length
if lastPercent = percent |> not then
printfn "progress: %d %%" percent
lastPercent <- percent
if n < data.BaseStream.Length then
let i2 = (i + 1) % 256
let j2 = (j + (key.[i2] |> int)) % 256
swap key i2 j2
let t = (key.[i2] + key.[j2]) |> int
let bk = key.[t % 256]
let b = data.ReadByte()
let r = bk ^^^ b
writer.Write r
compute data key i2 j2 writer (n + 1L)
let k1 = keySchedule password
let reader = new BinaryReader(content)
let writer = new BinaryWriter(output)
compute reader k1 0 0 writer 0L
writer.Flush()
let computeRc4str (password:string) (content:string) =
let plaintext = content |> Encoding.ASCII.GetBytes
use stream = new MemoryStream(plaintext)
use output = new MemoryStream()
computeRc4 password stream output
output.Position <- 0L
output.ToArray()
let passwd = "github"
//let crypted = computeRc4str passwd "Appli mobile"
//let output = new MemoryStream()
//let input = new MemoryStream(crypted)
//computeRc4 passwd input output
//output.Position <- 0L
//let decrypted = Encoding.ASCII.GetString(output.ToArray())
let testCrypt () =
use clearFile = File.OpenRead @"E:\epubs\ducobu.epub"
use cryptedFile = File.Open(@"E:\epubs\ducobu_epub.rc4", FileMode.Create)
computeRc4 passwd clearFile cryptedFile
cryptedFile.Flush()
let testDecrypt () =
use decryptedFile = File.Open(@"E:\epubs\ducobu-decrypted.epub", FileMode.Create)
use cryptedFile2 = File.OpenRead @"E:\epubs\ducobu_epub.rc4"
computeRc4 passwd cryptedFile2 decryptedFile
decryptedFile.Flush()
let watch = Stopwatch.StartNew()
testCrypt()
watch.Stop()
printfn "crypting time: %A" watch.Elapsed
watch.Reset()
watch.Start()
testDecrypt()
watch.Stop()
printfn "decrypting time: %A" watch.Elapsed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment