OCaml base64 encoder and validating decoder

OCaml
let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

let b64_encode s =
  let out = Buffer.create (4 * ((String.length s + 2) / 3)) in
  let acc = ref 0 and bits = ref 0 in
  String.iter (fun c ->
    acc := (!acc lsl 8) lor Char.code c; bits := !bits + 8;
    while !bits >= 6 do bits := !bits - 6; Buffer.add_char out alphabet.[(!acc lsr !bits) land 63] done) s;
  if !bits > 0 then Buffer.add_char out alphabet.[(!acc lsl (6 - !bits)) land 63];
  while Buffer.length out mod 4 <> 0 do Buffer.add_char out '=' done;
  Buffer.contents out

let b64_decode s =
  if String.length s mod 4 <> 0 then invalid_arg "base64: length must be a multiple of 4";
  let out = Buffer.create (3 * String.length s / 4) and acc = ref 0 and bits = ref 0 in
  String.iter (fun c ->
    if c <> '=' then begin
      let v = match String.index_opt alphabet c with Some v -> v | None -> invalid_arg "base64: bad character" in
      acc := (!acc lsl 6) lor v; bits := !bits + 6;
      if !bits >= 8 then (bits := !bits - 8; Buffer.add_char out (Char.chr ((!acc lsr !bits) land 255)))
    end) s;
  Buffer.contents out