(* Base64 *) (* $Id: base64.ml,v 1.1 2003/01/12 15:33:00 berke Exp $ *) (* By Berke Durak *) let code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" let encode_base64 s t m = let i = ref 0 and j = ref 0 and c = Char.code in let n = m - m mod 3 in while !i < n do t.[!j] <- code.[((c s.[!i]) lsr 2) land 63]; incr j; t.[!j] <- code.[(((c s.[!i]) land 3) lsl 4) lor ((c s.[!i + 1]) lsr 4)]; incr j; t.[!j] <- code.[(((c s.[!i + 1]) land 15) lsl 2) lor ((c s.[!i + 2]) lsr 6)]; incr j; t.[!j] <- code.[(c s.[!i + 2]) land 63]; incr j; i := !i + 3 done; begin match m mod 3 with | 1 -> t.[!j] <- code.[((c s.[!i]) lsr 2) land 63]; incr j; t.[!j] <- code.[((c s.[!i]) land 3) lsl 4]; incr j; t.[!j] <- code.[64]; incr j; t.[!j] <- code.[64]; incr j | 2 -> t.[!j] <- code.[((c s.[!i]) lsr 2) land 63]; incr j; t.[!j] <- code.[(((c s.[!i]) land 3) lsl 4) lor ((c s.[!i + 1]) lsr 4)]; incr j; t.[!j] <- code.[((c s.[!i + 1]) land 15) lsl 2]; incr j; t.[!j] <- code.[64]; incr j | _ -> (); end; !j (* f : function for outputting characters *) (* q : current state of encoder *) (* result : new state, side-effects via f *) type state = State0 | State1 of int | State2 of int * int let push_byte q f b = match q with | State0 -> State1(b) | State1(b0) -> State2(b0,b) | State2(b0,b1) -> List.iter f [ code.[(b0 lsr 2) land 63]; code.[((b0 land 3) lsl 4) lor (b1 lsr 4)]; code.[((b1 land 15) lsl 2) lor (b lsr 6)]; code.[b land 63] ]; State0 let flush_encoder q f = List.iter f (match q with | State0 -> [] | State1(b0) -> [ code.[(b0 lsr 2) land 63]; code.[(b0 land 3) lsl 4]; code.[64]; code.[64] ] | State2(b0,b1) -> [ code.[(b0 lsr 2) land 63]; code.[((b0 land 3) lsl 4) lor (b1 lsr 4)]; code.[(b1 land 15) lsl 2]; code.[64] ]) let cf m f = let i = ref 0 in fun c -> if !i = m then begin f '\n'; i := 0; end; incr i; f c let _ = let q = ref State0 in let f = cf 72 (output_char stdout) in try while true do q := push_byte !q f (Char.code (input_char stdin)) done with End_of_file -> flush_encoder !q f; flush stdout