我想使用字幕API。它需要md5哈希的第一个和最后64kb的视频文件。我知道如何做md5部分只是想知道如何获得128kb的数据。
以下是Java中我无法在Delphi中实现的问题的解决方案。 How to read first and last 64kb of a video file in Java?
到目前为止我的Delphi代码:
function TSubdbApi.GetHashFromFile(const AFilename: string): string;
var
Md5: TIdHashMessageDigest5;
Filestream: TFileStream;
Buffer: TByteArray;
begin
Md5 := TIdHashMessageDigest5.Create;
Filestream := TFileStream.Create(AFilename, fmOpenRead, fmShareDenyWrite);
try
if Filestream.Size > 0 then begin
Filestream.Read(Buffer, 1024 * 64);
Filestream.Seek(64, soFromEnd);
Filestream.Read(Buffer, 1024 * 64);
Result := Md5.HashStreamAsHex(Filestream);
end;
finally
Md5.Free;
Filestream.Free;
end;
end;
我没有得到官方API所述的准确md5哈希值。API url here。我正在使用Delphi XE8。
答案 0 :(得分:7)
该API使用的hash function
描述为:
我们的哈希是由第一个和最后一个64kb组成的 视频文件,将所有内容放在一起并生成md5 数据(128kb)。
我可以在您的代码中看到一些问题。您正在散列文件流,而不是您的Buffer
数组。除非您通过后续读取文件流覆盖该数组。并且您试图仅搜索64个字节,并且超出流的末尾(您需要使用负值来从流的末尾搜索)。尝试这样的事情:
type
ESubDBException = class(Exception);
function TSubdbApi.GetHashFromFile(const AFileName: string): string;
const
KiloByte = 1024;
DataSize = 64 * KiloByte;
var
Digest: TIdHashMessageDigest5;
FileStream: TFileStream;
HashStream: TMemoryStream;
begin
FileStream := TFileStream.Create(AFileName, fmOpenRead, fmShareDenyWrite);
try
if FileStream.Size < DataSize then
raise ESubDBException.Create('File is smaller than the minimum required for ' +
'calculating API hash.');
HashStream := TMemoryStream.Create;
try
HashStream.CopyFrom(FileStream, DataSize);
FileStream.Seek(-DataSize, soEnd);
HashStream.CopyFrom(FileStream, DataSize);
Digest := TIdHashMessageDigest5.Create;
try
HashStream.Position := 0;
Result := Digest.HashStreamAsHex(HashStream);
finally
Digest.Free;
end;
finally
HashStream.Free;
end;
finally
FileStream.Free;
end;
end;