subroutine sha3_file( d, fname, hdigest )
! hashes a file and either returns the sha3_hexdigest in a string, or display it to
! stdout, along with the file name. d is the digest size in bits (224,256,384,512)
use M_system, only : system_stat
integer, intent(in) :: d
character(len=*), intent(in) :: fname
character(len=*), optional, intent(out) :: hdigest
integer(kind=int8), dimension(d/8) :: digest
logical :: fexist
integer :: fsize, i, j, nread, nrem
type(sha3_state) :: S
integer(kind=int8), dimension(:), allocatable :: buffer
integer(kind=int64), dimension(13) :: values
character(len=128) :: dg
! does this file exist? if yes, what is its size?
inquire( file=trim(adjustl(fname)), exist=fexist )
if ( .not. fexist ) then
print *, 'file not found.'
return
endif
call system_stat( trim(fname), values )
fsize = int(values(8))
! read the file into a buffer with the appropriate size
allocate( buffer(4096) )
open( unit=39, file=trim(adjustl(fname)), form='unformatted', access='direct', recl=1 )
nrem = fsize
j = 0
do
nread = min(nrem,4096)
do i = 1, nread
j = j + 1
read( 39, rec=j ) buffer(i)
enddo
if ( nread == 4096 ) then
call sha3_update( S, buffer, d )
else
call sha3_update( S, buffer(1:nread), d )
endif
nrem = nrem - nread
if ( nrem <= 0 ) exit
enddo
close( 39 )
call sha3_digest( S, digest )
dg = sha3_hexdigest( digest )
if ( present(hdigest) ) then
hdigest = trim(dg)
else
print '(3a)', trim(dg), ' ', trim(fname)
endif
deallocate( buffer )
end subroutine sha3_file