Core base64 encoder (allocatable output)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int8), | intent(in) | :: | bytes(:) | |||
| integer, | intent(in) | :: | nbytes | |||
| character(len=:), | intent(out), | allocatable | :: | output |
subroutine base64_encode_bytes(bytes, nbytes, output) !! Core base64 encoder (allocatable output) use iso_fortran_env, only: int8 implicit none integer(int8), intent(in) :: bytes(:) integer, intent(in) :: nbytes character(:), allocatable, intent(out) :: output character(64), parameter :: b64 = & 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' integer :: i, j, ngroups, out_len integer :: b0, b1, b2, idx ngroups = (nbytes + 2) / 3 out_len = ngroups * 4 allocate(character(out_len) :: output) j = 1 do i = 1, nbytes, 3 b0 = iand(int(bytes(i)), 255) if(i + 1 .le. nbytes)then b1 = iand(int(bytes(i+1)), 255) else b1 = 0 end if if(i + 2 .le. nbytes)then b2 = iand(int(bytes(i+2)), 255) else b2 = 0 end if idx = ishft(b0, -2) + 1 output(j:j) = b64(idx:idx) idx = ior(ishft(iand(b0, 3), 4), ishft(b1, -4)) + 1 output(j+1:j+1) = b64(idx:idx) if(i + 1 .le. nbytes)then idx = ior(ishft(iand(b1, 15), 2), ishft(b2, -6)) + 1 output(j+2:j+2) = b64(idx:idx) else output(j+2:j+2) = '=' end if if(i + 2 .le. nbytes)then idx = iand(b2, 63) + 1 output(j+3:j+3) = b64(idx:idx) else output(j+3:j+3) = '=' end if j = j + 4 end do end subroutine base64_encode_bytes