我的OSDB哈希算法出了什么问题?

时间:2016-05-22 13:48:00

标签: c# algorithm hash uwp subtitle

我正在尝试编写一个c#算法来从在线视频文件中获取哈希值以搜索(https://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes

上的字幕

我的想法是该算法被提供给视频文件的url,并返回哈希值。简单。问题是,我没有得到正确的价值。根据我链接的页面,this file应该返回8e245d9679d31e12,但我得到00c4fcb4aa6f763e。这是我的C#:

public static async Task<byte[]> ComputeMovieHash(string filename)
{
    long filesize = 0;

    //Get File Size
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(filename);
    req.Method = "HEAD";
    var resp = await req.GetResponseAsync();
    filesize = resp.ContentLength;
    long lhash = filesize;

    //Get first 64K bytes
    byte[] firstbytes = new byte[0];
    using (HttpClient client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Range", "bytes=0-65536");
        using (HttpResponseMessage response = await client.GetAsync(filename))
        {
            Debug.WriteLine("getting first bytes (bytes=0-65536)");
            firstbytes = await response.Content.ReadAsByteArrayAsync();
        }
    }
    lhash += BitConverter.ToInt64(firstbytes, 0);

    //Get last 64K bytes
    byte[] lastbytes = new byte[0];
    using (HttpClient client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Range", "bytes=" + (filesize - 65536) + "-" + filesize);
        using (HttpResponseMessage response = await client.GetAsync(filename))
        {
            Debug.WriteLine("getting last bytes (" + "bytes=" + (filesize - 65536) + "-" + filesize + ")");
            lastbytes = await response.Content.ReadAsByteArrayAsync();
        }
    }
    lhash += BitConverter.ToInt64(lastbytes, 0);

    //Return result
    byte[] result = BitConverter.GetBytes(lhash);
    Array.Reverse(result);
    Debug.WriteLine("RESULT=" + ToHexadecimal(result));
    return result;
}

我做错了什么?我把它与opensubtitles.org给出的代码进行了比较,似乎它应该有相同的结果:/

1 个答案:

答案 0 :(得分:1)

您的代码中有几处错误:

  1. 范围bytes=0-65536会返回6553 7 个字节,这个字节太多了。

  2. 您不计算64位校验和,因为BitConverter.ToInt64(firstbytes, 0)占用前8个字节并将它们转换为数字,其余65536-8个字节被完全忽略。

  3. 固定版本应该是这样的:

    public static async Task<byte[]> ComputeMovieHash(string filename) {
        long filesize = 0;
    
        //Get File Size
        HttpWebRequest req = (HttpWebRequest) WebRequest.Create(filename);
        req.Method = "HEAD";
        var resp = await req.GetResponseAsync();
        filesize = resp.ContentLength;
        long lhash = filesize;
    
        //Get first 64K bytes
        byte[] firstbytes;
        using (HttpClient client = new HttpClient()) {
            client.DefaultRequestHeaders.Add("Range", "bytes=0-65535");
            using (HttpResponseMessage response = await client.GetAsync(filename)) {
                Debug.WriteLine("getting first bytes (bytes=0-65535)");
                firstbytes = await response.Content.ReadAsByteArrayAsync();
            }
        }
        for (int i = 0; i < firstbytes.Length; i += sizeof (long)) {
            lhash += BitConverter.ToInt64(firstbytes, i);
        }
    
        //Get last 64K bytes
        byte[] lastbytes;
        using (HttpClient client = new HttpClient()) {
            client.DefaultRequestHeaders.Add("Range", "bytes=" + Math.Max(filesize - 65536, 0) + "-" + filesize);
            using (HttpResponseMessage response = await client.GetAsync(filename)) {
                Debug.WriteLine("getting last bytes (" + "bytes=" + (filesize - 65536) + "-" + filesize + ")");
                lastbytes = await response.Content.ReadAsByteArrayAsync();
            }
        }
        for (int i = 0; i < lastbytes.Length; i += sizeof (long)) {
            lhash += BitConverter.ToInt64(lastbytes, i);
        }
    
        //Return result
        byte[] result = BitConverter.GetBytes(lhash);
        Array.Reverse(result);
        return result;
    }