c# - 我的 OSDB 哈希算法有什么问题?

标签 c# algorithm hash uwp subtitle

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

我的想法是,该算法被提供给视频文件的 url,并返回哈希值。简单的。问题是,我没有得到正确的值(value)。根据我链接到的页面,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. Range bytes=0-65536 将返回 65537 字节,多了一个字节。

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

固定版本应该是这样的:

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;
}

关于c# - 我的 OSDB 哈希算法有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37375176/

相关文章:

c# - 检查 C# 中的日期范围是否连续?

c# - 使用BackGroundWorker的错误处理条件失败

algorithm - 修改 Euler Totient 函数

c# - 从 C# SSH.NET 的 ShellStream 获取完整的命令输出

c# - DevExpress 设置 XtraTab 选中页面

php - 尝试创建一个页面,如果是第一次登录,则检查纯文本密码,否则检查哈希密码(php)

java - Apache Shiro - 密码格式问题

c++ - vector<double> 的哈希函数

algorithm - Codility Peaks 复杂性

python - 以最公平的方式分配资源