2017-09-14 94 views
1

我需要根据比特币工作算法算法比较sha256哈希值。所以需要通过设置一个目标难度来创建一个上限,然后创建数据+随机数的哈希值并将其与上边界进行比较。如果这个计算值小于上限,那么这是一个有效的工作证明。如何比较2 BigIntegers的十六进制表示法

因此,这意味着我们的上边界,即target可以被定义为

var target = new BigInteger(1) << 256 - 24 

当我们创建新块的哈希值,然后我们用target进行比较。即

var hashInt = new BigInteger(hashBytes) 
if (hashInt.CompareTo(target) == -1) { 
    //It is a valid hash 
} 

对于这个问题,让我们假设值会

target

6901746346790563787434755862277025452451108972170386555162524223799296 

hashInt

-50765282004551092829298895592266344483300201926640276338429566691241878315064 

和他们的十六进制值是(这是通过调用计算.ToString("x")关于这些变量)

target

10000000000000000000000000000000000000000000000000000000000 

hashInt

8fc3de5d792f2e6b3118697d1e5baa405400e9f8f09625d7eed1481ee0b09fc8 

现在,当我们这样做hashInt.CompareTo(target) == -1然后返回true。我完全理解这是为什么,但我想要做的是比较它们的十六进制值,如果我们能够做到这一点,那么比较它将返回false这正是我想要的。

+2

你什么意思是比较十六进制值?你想达到什么目的? –

+0

我认为你想通过模比较这个数字。如果这样的话''| b | > | a |'将是正确的。 –

+0

重要的是要知道你试图用这个来实现什么,因为一些对固定大小的整数有意义的解决方案只能扩展到BigInteger的理想化表示,而不是实际的可变长度表示。 – Ryan

回答

2

可以比较相同长度的两个序列与Zip

static int CompareSequenceTo<T>(this IEnumerable<T> a, IEnumerable<T> b) where T : IComparable<T> { 
    return a 
     .Zip(b, (x, y) => x.CompareTo(y)) 
     .FirstOrDefault(r => r != 0); 
} 

适用于困难a和哈希b,它正确地报告a小于b

byte[] a = {0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
byte[] b = {0x8f, 0xc3, 0xde, 0x5d, 0x79, 0x2f, 0x2e, 0x6b, 0x31, 0x18, 0x69, 0x7d, 0x1e, 0x5b, 0xaa, 0x40, 0x54, 0x00, 0xe9, 0xf8, 0xf0, 0x96, 0x25, 0xd7, 0xee, 0xd1, 0x48, 0x1e, 0xe0, 0xb0, 0x9f, 0xc8}; 

Console.WriteLine(a.CompareSequenceTo(b)); // some value less than zero 
+0

我已经添加了这个和正在运行的代码。如果它能正常工作,我会让你知道并接受你的答案。谢谢 – adeel41

+0

我对比特币了解不多,但我认为一般来说哈希值只有在比较平等时才有意义。有比较大于或小于比特币哈希的语义吗? –

+1

@KlitosKyriacou:理想情况下,散列就像一个随机值,所以如果你尝试一个随机输入,你就有一定的机会获得一个小于其他值的输出。这个例子要求哈希具有24位零的前缀。由于您可以将散列的前24位作为一致随机对待,因此这对应于2^-24的概率(即,在计算总体散列函数1160万次后,挖掘块的概率为50%)。 – Ryan