4

我想使用字幕 API。它需要视频文件的第一个和最后一个 64kb 的 md5 哈希。我知道如何做 md5 部分只是想知道我将如何获得 128kb 的数据。

这是我无法在 Delphi 中实现的 Java 问题的解决方案。如何在 Java 中读取视频文件的第一个和最后一个 64kb?

到目前为止我的德尔福代码:

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 网址在这里。我正在使用德尔福 XE8。

4

1 回答 1

7

hash functionAPI 使用的描述为:

我们的哈希由视频文件的第一个和最后一个 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;
于 2015-05-13T21:27:28.457 回答