Created
July 2, 2015 15:41
-
-
Save rflechner/0b468b7adac4be463412 to your computer and use it in GitHub Desktop.
RC4 stream encoding and decoding (bad performances)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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