【问题标题】:dc (desk calculator) - hashes typedc(桌面计算器) - 哈希类型
【发布时间】:2014-10-12 10:59:12
【问题描述】:

在 TLDP 上阅读此页面:http://www.tldp.org/LDP/abs/html/mathc.html

我找到了以下命令:

bash$ echo "16i[q]sa[ln0=aln100%Pln100/snlbx]sbA0D68736142snlbxq" | dc
Bash

我只是想知道:有人知道那是什么类型的散列,以及我如何转换简单的文本来生成那种散列?

谢谢

【问题讨论】:

  • 是的,谢谢,这就是我所做的。不幸的是,我找不到我要找的东西。我想 perl 中有一种方法可以编码或解码那种类型的哈希或字符串,但我不知道如何。
  • dc 没有哈希值。 [...] 创建一个字符串。
  • This site 看起来像 dc 上的一个不错的教程。
  • 我不认为dc 这些天被大量使用,所以您可能需要等待一段时间,让知道它的人来为您翻译。也许网站的作者可以帮助你。
  • 从 tldp.org 上显示命令的方式来看,它的设计似乎让人困惑——这是 dc experts 的一个例子,展示了他们可以编写多么神秘的东西。跨度>

标签: bash perl dc


【解决方案1】:

比较好的教程是here。使用它,你会得到下一个分解:

  • 16i - 输入将是十六进制(如bc - ibase=16)
  • [q] - [..] 的意思是字符串。因此,这会将字符串 q 存储到堆栈顶部。通常[....] 是存储以供以后执行的一系列命令(如宏),在这种情况下命令q - 退出。
  • s - 取栈顶并将其存储到由下一个字母标识的寄存器中,因此在这种情况下,[q]sa 一起意味着:将字符串 q 存储到寄存器 a
  • 下同,将字符串ln0=aln100%Pln100/snlbx存入寄存器b
  • 下一个A0D68736142sn,将A0D68736142存入寄存器n。在这种情况下不是字符串,而是因为我们输入了十六进制,所以这是一个十六进制数

以上是一个类似的准备阶段,翻译成通用编程语言:

$a = "q";
$b = "ln0=aln100%Pln100/snlbx";
$n = 0xA0D68736142";

堆栈现在是空的(所有内容都存储在注册表中)。

接下来是最后的计算:

  • l 的意思是从后面的寄存器中取值,并把它放到栈顶,所以lb 的意思是:取寄存器b 的值。
  • x 的意思是:将其作为一系列命令执行 - 在这种情况下,将其读取为 eval "$b";
  • 最后一个q表示退出

现在需要分解ln0=aln100%Pln100/snlbx(寄存器b 的内容 - eval-ing 是什么。)

  • ln - 如上所述,在我们的例子中从寄存器 n 中获取值:十六进制数
  • 接下来是一个棘手的部分:0=a,取栈顶,如果是zero,则执行存储在注册表“a”中的字符串(宏)(在我们的例子中,这是一个“q” -退出),例如喜欢:
if( $n == 0 ) eval "a"; #a contains "q" = quit
  • 如果$n 不为零,则再次获取regsiter n 的内容(ln)(放到栈顶)
  • 将数字100(是十六进制)放到栈顶
  • % 将堆栈顶部的两个数字取模(因此:$n % 0x100)并将其放在堆栈顶部
  • 将栈顶打印为 ascii 字符串 (chr($stack))
  • ln 再次取数 $n (再次,它来到栈顶)
  • 将100 放入堆栈
  • /在栈中除数(结果排在最前面)
  • sn将栈存入$n(替换原来的编号)
  • lbx - 如上所述 - 评估寄存器 b

所以,简而言之:

  • 来自存储在$n中的号码0xA0D68736142,
  • 通过0x100取模得到最后两位数,将其转换为ascii并打印出来,
  • 除以0x100(删除最后两位数)-并将其存储到$n
  • 重复直到什么都没有(零)

对于0xA0D68736142,您将获得(使用man ascii)

  • 42 - B
  • 61 - a
  • 73 - s
  • 68 - h
  • 0D - \r
  • A(作为 0A)-\n

使用 perl 从普通 ascii 字符串创建这样的十六进制字符串

perl -E '$s=reverse("Bash\r\n");$s =~ s/(.)/sprintf("%02x",ord($1))/seg;say uc $s'

打印

0A0D68736142

或

perl -E '$s=reverse("Stackoverflow rocks\n");$s =~ s/(.)/sprintf("%02x",ord($1))/seg;say uc $s'

0A736B636F7220776F6C667265766F6B63617453

和

echo "16i[q]sa[ln0=aln100%Pln100/snlbx]sb0A736B636F7220776F6C667265766F6B63617453snlbxq" | dc

打印:

Stackoverflow rocks

Ps:dc 是一件奇怪的事情 - 它更容易阅读和理解“程序”作为创建一个。 :)

【讨论】:

  • @Hector 这不是“dc-string”,而是字符串的简单十六进制值。您可以使用man ascii 手动创建一些或查看 perl 脚本的编辑。
  • @Hector - 如果您对答案感到满意,您还可以在答案处点击接受(绿色标记)... :)
猜你喜欢
  • 2015-10-26
  • 2016-06-23
  • 1970-01-01
  • 2013-10-19
  • 2017-02-04
  • 2012-04-14
  • 2014-01-14
  • 1970-01-01
  • 2017-02-20
相关资源
最近更新 更多