电子邮件地址的整数形式

今天在浏览别人博客时,偶然看到博主的电子邮件地址很奇怪,是dc -e xxxxxxxxxxxxxP的形式,在shell下运行了,果然输出了电子邮件地址,好神奇啊。

这么神的电子邮件地址,我也想有一个,所以就查了下,原来dc是linx下的栈式任意精度计算器,用逆波兰形式来表示,所有的操作都在栈中进行。还有个bc命令,它与dc是什么关系呢,在UNIX下,bc是dc的一个前端,就是说bc实际上是用dc而完成计算的,它只不过作了一些预处理工作,使它更方便用户使用;而在Linux下,bc用的是GNU bc,它是一个与dc毫不相关的独立程序。

说了这么多,那我怎么才能得到这么神奇的电子邮件地址呢?

首先要明白那个dc命令是什么意思,这个可以man dc查看。dc -e xxxxxxxxxxxxxP,是将xxxxxxxxxxxxx压栈,然后P命令将栈顶以字符串的形式输出,字符串中每个字符的值都是通过取模(模为256)得到的,结果就是电子邮件地址了。

这样,我们要做的就是把电子邮件地址这个字符串转为一个整数,整数的值为字符串按权值从左到右减的形式算得的值,基数为256,也即8位bit的ASCCI码的模。

计算公式x(i) * 256^(i-1) + x(i-1) * 256^(i-1-1)+……+x(1):

下面给出字符串到大整数转换的bash脚本string-to-big-number.sh

  
#! /bin/sh

#函数作用
  
#把一个任意长度的字符串转化为一个大整数,字符串从左到右权值变小

#可以给一个邮件地址作为参数,然后得到一个大整数
  
#然后可以用dc命令从整数得到电子邮件地址
  
#dc -e xxxxxP
  
#xxxxx为运行程序结束时得到的一个长整数
  
#P为dc中的输出命令

script_name=$(basename $0) #script name

#一个简单的帮助函数
  
usage ()
  
{
	  
echo
      
echo "USAGE: $script\_name your\_email_address"
	  
echo
	  
echo
	  
echo "Example:"
	  
echo " $script_name example@example.com"
	  
echo
	  
echo
	  
exit 1
  
}

if [[ -z "$@" ]]
  
then
	  
usage
  
else

email_address="$@"
  
fi

declare -a num_array
  
#od命令是为了将字符串转为整数形式
  
#tr命令是为了去除od命令产生的每16字节的回车。不过试了下,好像可以不用去除
  
#直接就可以num\_array=(\`echo $email\_address | od -An -t dC \`)

num\_array=(\`echo $email\_address | od -An -t dC | tr -d "\n"\`)
  
num\_array=(\`echo $email\_address | od -An -t dC \`)

answer=$(echo ${num\_array[0]}*${num\_array[2]} | bc)

length=${#num_array[@]}

tmp=1
  
answer=0

for(( i=$length-1;i>=0;i– ))
  
do
	  
tmp=${num_array[$i]}
	  
for(( j=$length-1-$i;j>0;j– ))
	  
do
		  
tmp=$(echo $tmp*256|bc)
		  
#这里用到tr命令是因为,当tr的输出长度超过68位时会输出一个断行的标志
		  
#字符串"\ ",这里把它去除,不然当你的输出字符串超过27时就会出错
		  
#也可以这样tmp=$(echo $tmp|tr -d ‘\\\ ‘)
		  
tmp=$(echo $tmp|tr -d "\\\\\ ")
	  
done
	  
answer=$(echo $answer+$tmp | bc)
		  
#这里用到tr命令是因为,当tr的输出长度超过68位时会输出一个断行的标志
		  
#字符串"\ ",这里把它去除,不然当你的输出字符串超过27时就会出错
		  
#也可以这样tmp=$(echo $tmp|tr -d ‘\\\ ‘)
	  
answer=$(echo $answer|tr -d "\\\\\ ")

done

echo $answer
  

试用举例:

用我自己的邮箱测试下:

  
>./string-to-big-number.sh lonelyibex@gmail.com
  
158478336724523558231355197806041675486339888278794
  

如何找回邮件地址呢?

  
>dc -e 158478336724523558231355197806041675486339888278794P
  
lonelyibex@gmail.com
  

哈哈,出来了吧。

这样就再也不怕网络垃圾邮件了。

再看一个好玩的:

  
>dc -e 6210311416885776882064095332186488690375381188833444908746308655633507
  
3029213711782268384217314297776641370186061300200882451991072479873368332294
  
0386450189284826824257730936022632689790257544368080047034455808265517031663
  
1506345335835739126208462505365174992730467747066981287672993055897050191074
  
4147189069583852539002525228214538P
  
I’m lonelyibex,welcome to send me messages. My email:lonelyibex@gmail.com My jabber ID:fungo@jabber.org irc:lonelyibex (irc.freenode.net)
  
孤独的北山羊 /
Published under (CC) BY-NC-SA in categories GNU/Linux  tagged with dc  整数串  电子邮件地址