我的 OSDB 哈希算法有什么问题?
What's wrong with my OSDB hash algorithm?
我正在尝试编写一个 c# 算法来从在线视频文件中获取哈希以搜索 (https://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes)
上的字幕
我的想法是,该算法将 url 提供给视频文件,然后 return 提供哈希值。简单的。问题是,我没有得到正确的价值。根据我链接到的页面,this file 应该 return 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 给出的代码进行了比较,看起来它应该有相同的结果:/
您的代码中有几个错误:
范围bytes=0-65536
将return你65537字节,多了一个字节。
你不计算 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# 算法来从在线视频文件中获取哈希以搜索 (https://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes)
上的字幕我的想法是,该算法将 url 提供给视频文件,然后 return 提供哈希值。简单的。问题是,我没有得到正确的价值。根据我链接到的页面,this file 应该 return 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 给出的代码进行了比较,看起来它应该有相同的结果:/
您的代码中有几个错误:
范围
bytes=0-65536
将return你65537字节,多了一个字节。你不计算 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;
}