【问题标题】:Confusing base conversion from bytes to hex从字节到十六进制的令人困惑的基本转换
【发布时间】:2013-02-02 23:20:48
【问题描述】:

我在处理这段代码时遇到了一些问题。 QByteArray::number 应该从哈希中获取 QByteArray 并将其转换为十六进制,但结果比我预期的要短得多。我在想两个输出应该是一样的。我认为这与指针转换有关,但我不明白该转换做得好到足以看到如何进行价值。

谁能解释为什么这两行输出不同的结果?最好用数学术语。

代码

QCryptographicHash hash(QCryptographicHash::Sha1);
hash.addData("some string to hash");
qDebug() << QByteArray::number(*(qlonglong*)hash.result().data(), 16);
qDebug() << hash.result().toHex();

输出:

"89bde3ca56c83c47" 
"473cc856cae3bd89e43ff9f62963d6f38372ccbd" 

预期输出:

"473cc856cae3bd89e43ff9f62963d6f38372ccbd" 
"473cc856cae3bd89e43ff9f62963d6f38372ccbd" 

注意:我的实际问题是基数为 36,而不是 16,但有一个方便的 .toHex 方法可以让这更容易显示。

【问题讨论】:

  • 猜测,qlonglong 可能是 64 位,这对于容纳 SHA-1 哈希(160 位)来说太小了。
  • JerryCoffin,我忘记了 C++ 编译器假设你知道你在用指针做什么。因此习惯于不允许使用会截断数据的强制转换的语言。

标签: c++ qt pointers


【解决方案1】:

在您的代码中,hash.result().data() 指向 160 位(20 字节)的数据。 qlonglong 是您平台上的 64 位(8 字节)数据。

*(qlonglong*)hash.result().data() 将哈希结果的前 8 个字节重新解释为数字。您的平台是小端平台,因此哈希数据的第一个字节被解释为结果数字的低字节。

因此,64 位数字(以十六进制形式查看)以相反的顺序显示哈希数据的前 8 个字节。您可以在输出中看到:

89 bd ... 3c 47

是开头部分的反面

47 3c ... bd 89    e4 3f ...

【讨论】:

  • 有道理。很高兴我只是假设 sha1 适合 64 位。谢谢
【解决方案2】:

您实际上是将string(作为const char*)转换为long long*,然后解除对它的引用,并将返回的任何数值返回给QByteArray 的构造函数。不使用 qt 类,你正在这样做:

std::string s = "1b3";
const char* cc = s.c_str();

std::cout<<cc<<std::endl;
std::cout<<*(long long*)cc<<std::endl;

你得到相同的字符串吗?不,你没有。

output:
1b3
3367473

这不是数学问题...这是将 char* 转换为 long long* 并期望得到有效数值作为结果的问题。

【讨论】:

  • 显然hash.result不是一个字符串,而是一个代表字节序列的类(可能是QByteArray)所以它的data()方法指向原始二进制数据。
  • @JoergB 我对QByteArray::datadocs 提到“返回的字符串”感到困惑。我认为你是对的。
猜你喜欢
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2017-09-13
相关资源
最近更新 更多