Encode a bits stream (must be multiple of 24 bits) into base64 charcaters code (of length multiple of 4).
The bits stream are encoded in chunks of 24 bits as the following example (in little endian order)
+--first octet--+-second octet--+--third octet--+ |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| +-----------+---+-------+-------+---+-----------+ |5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0| +--1.index--+--2.index--+--3.index--+--4.index--+
The 4 indexes are stored into 4 elements 8 bits array, thus 2 bits of each array element are not used.
The number of paddings must be computed outside this procedure, into the calling scope.
This procedure is the backend of encoding, thus it must be never called outside the module.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=I1P), | intent(in) | :: | bits(1:) | Bits to be encoded. |
||
integer(kind=I4P), | intent(in) | :: | padd | Number of padding characters ('='). |
||
character(len=*), | intent(out) | :: | code | Characters code. |
pure subroutine encode_bits(bits, padd, code)
!< Encode a bits stream (must be multiple of 24 bits) into base64 charcaters code (of length multiple of 4).
!<
!< The bits stream are encoded in chunks of 24 bits as the following example (in little endian order)
!<```
!< +--first octet--+-second octet--+--third octet--+
!< |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
!< +-----------+---+-------+-------+---+-----------+
!< |5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0|
!< +--1.index--+--2.index--+--3.index--+--4.index--+
!<```
!< @note The 4 indexes are stored into 4 elements 8 bits array, thus 2 bits of each array element are not used.
!<
!< @note The number of paddings must be computed outside this procedure, into the calling scope.
!<
!< @warning This procedure is the backend of encoding, thus it must be never called outside the module.
integer(I1P), intent(in) :: bits(1:) !< Bits to be encoded.
integer(I4P), intent(in) :: padd !< Number of padding characters ('=').
character(*), intent(out) :: code !< Characters code.
integer(I1P) :: sixb(1:4) !< 6 bits slices (stored into 8 bits integer) of 24 bits input.
integer(I8P) :: c !< Counter.
integer(I8P) :: e !< Counter.
integer(I8P) :: Nb !< Length of bits array.
Nb=size(bits,dim=1,kind=I8P)
c = 1_I8P
do e=1_I8P,Nb,3_I8P ! loop over array elements: 3 bytes (24 bits) scanning
sixb = 0_I1P
call mvbits(bits(e ),2,6,sixb(1),0)
call mvbits(bits(e ),0,2,sixb(2),4)
if (e+1<=Nb) then
call mvbits(bits(e+1),4,4,sixb(2),0)
call mvbits(bits(e+1),0,4,sixb(3),2)
endif
if (e+2<=Nb) then
call mvbits(bits(e+2),6,2,sixb(3),0)
call mvbits(bits(e+2),0,6,sixb(4),0)
endif
sixb = sixb + 1_I1P
code(c :c ) = base64(sixb(1):sixb(1))
code(c+1:c+1) = base64(sixb(2):sixb(2))
code(c+2:c+2) = base64(sixb(3):sixb(3))
code(c+3:c+3) = base64(sixb(4):sixb(4))
c = c + 4_I8P
enddo
if (padd>0) code(len(code)-padd+1:)=repeat('=',padd)
endsubroutine encode_bits