加密哈希函数
让我们首先看一下哈希,这个例子的所有资源都可以在GitHub上找到。在密码学中,散列算法接受输入并生成固定大小的hash,称为输出摘要。摘要是确定性且不可逆的,这意味着相同的输入将始终生成相同的输出,并且输出无法反转以获得原始输入。良好的散列算法通过在最短的计算时间内使用“高难度”来最小化输出冲突。冲突或碰撞是两种不同输入产生相同输出的可能性。
通常我们将使用哈希函数进行身份验证和索引数据,我喜欢将其视为压缩唯一性的方法。例如,比较两个任意大小的文件或用户电子邮件将是时间密集的并且暴露易受攻击的用户数据。我们可以通过散列文件内容或用户电子邮件来生成指纹,并使用散列结果更有效地索引和比较数据。
这就像我们现在需要知道的那样多,但是如果你有强烈的好奇心,那么我会鼓励一些积极的谷歌搜索,或者看看Blockgeeks关于密码哈希函数的输入和输出的文章。
编写我们的哈希函数
现在我们已经对哈希有了非常基本的了解,我们可以研究如何在我们的EOS智能合约中生成自己的哈希。我们将创建一个接受输入string
并输出checksum256
散列摘要的动作,然后为了本示例的目的,打印结果。
让我们首先从EOS框架中引入crypto.h
库和EOS print.h
。
include <eosiolib/crypto.h>
- 注意我们文件名
crypto.h
的扩展名是 .h。这意味着我们使用的是C库而不是C++,因此我们的方法将使用C类型输入。
现在我们可以定义我们的动作并为我们的checksum256
输出分配一个参考。
checksum256 sum{};
- EOS框架为各种散列算法提供了一组方法。我们将使用
sha256
这个例子,因为它在大多数情况下都是快速,安全和典型的。
sha256(const_cast<char*>(str.c_str()), str.size(), &sum);
- 我们的
sha256
方法需要C类型的输入,所以我们首先需要将我们转换string
为一个char
集合,然后传递string
一个checksum256
引用的大小和一个将使用输出摘要更新的引用。现在剩下的就是打印散列输出结果。
printhex(&sum, sizeof(sum));
- 我们也可以返回
checksum256
此处并将其用作private内部操作。
进一步 - 校验和字符串
这个实现的功劳归功于Miguel Mota开发的解决方案,将checksum256转换为十六进制字符串。
那么如果我们想将我们的摘要转换成十六进制字符串会发生什么呢?为此,我们需要一种新方法。首先,让我们为输入参数定义一个模板并定义方法本身。此模板在方法定义之外定义,通常位于文件的顶部。模板只允许我们在调用函数时定义变量类型,然后编译器将负责替换并使其全部工作。
template <typename CharT>
string to_hex(const CharT* data, uint32_t length) {
// Method Body
}
- 现在我们可以开始研究我们方法的主体了。首先,我们将创建
string
类型的变量result
,我们的结果是创建一个用于char
从稍后绘制字符的集合,并将我们的数据强制转化为uint8_t
。
string result;
const char* hex_chars = "0123456789abcdef";
uint8_t* c = (uint8_t*)data;
- 最后,我们将迭代
char
输入数据中的每一个,匹配相应的十六进制字符,并将其附加到我们的结果string
。
for (uint32_t i = 0; i < length; ++i) {
(result += hex_chars[(c[i] >> 4)]) += hex_chars[(c[i] & 0x0f)];
}
return result;
- 1就是这样!现在,我们已经有了从
char
集创建checksum256
的方法,将其转换方法checksum256
为string
。在下一篇文章中,我们将讨论单例以及如何利用它们来存储应用程序状态和配置。