今天网友 再见理想50 给了我一段程序:
void main(int a)
{
char* x = "bB_Z#^B_Z#h1AI.BMB5#VB2]2:B]]=6#RB@1.]]L12#NB6N:]BN#JFHL1@D6#";
while(a = *x / 4) a -= 8, printf("\n%*s" + !!a, a, "_/_/_/" + *x++ % 4 * 2);
}
据说是某个大牛写的。这个程序并不难看,基本上都是数据,并不是某些什么“模糊代码比赛”. 运行效果如下:
但是要了解其工作原理也花费了一些时间。下面是我的注释,欢迎指正:
void showMe( char const* x )
{
int a;
while( a = *x / 4 )
{
a -= 8; //偏移
printf( "\n%*s" + (int)(bool)a, //是否换行, a == 0
a, //含空格字数.... 除数
"_/_/_/" + *x++ % 4 * 2); //字符个数 0-3....余数
}
}
我想,能不能反过来编码自己的数据呢。继而写了个编码程序,图形 "do" 编码成"P88;#Ra`8S#RbQQS#RbBjS#RbQQK#Ra`8C#P88C#" 替换了一下。
void main(int a)
{
char* x = "P88;#Ra`8S#RbQQS#RbBjS#RbQQK#Ra`8C#P88C#";
while(a = *x / 4) a -= 8, printf("\n%*s" + !!a, a, "_/_/_/" + *x++ % 4 * 2);
}
最关键的算法:
(blockNum*2 + charNum*2 + 8) * 4 + (MAX_CHAR_NUM - charNum)
其中,blockNum 是空格数, charNum是字符串,MAX_CHAR_NUM(3) 是一次编码最长的字符数,至于空格有没有这个限制,没有继续研究。为什么要*2呢,因为打印的时候,其实"_/_/_/" 是6个字,也就是每个原始字符他加大了一倍,不过也许本来就是这样,不得而知了。
下面是代码列表:
string make_ShowMeString()
{
char const* source = " xxxxxxxxx \n"
" x xx xxxxxx \n"
" x x xx xx \n"
" x x x x \n"
" x x xx xx \n"
" x xx xxxxxx \n"
" xxxxxxxxx \n";
cout << "source:" << endl << source << endl;
//编码
int const start_state = 0;
int const block_state = 1;
int const char_state = 2;
int const enter_state = 3;
int const oneok_state = 4;
int const end_state = -1;
int const MAX_CHAR_NUM = 3;
int state = 0;
int blockNum = 0;
int charNum = 0;
string dest;
char c;
while ( state != end_state )
{
switch (state)
{
case start_state:
if (*source == '\0')
{
state = end_state;
}else if (*source == ' ')
{
state = block_state;
}
else if (*source == '\n')
{
state = enter_state;
}
else
{
state = char_state;
}
break;
case block_state:
++blockNum;
if (*source == '\0')
{
state = oneok_state;
}else if (*source == ' ')
{
state = block_state;
}
else if (*source == '\n')
{
state = oneok_state;
}
else
{
state = char_state;
}
break;
case char_state:
++charNum;
if (charNum == MAX_CHAR_NUM)
{
state = oneok_state;
}
else if (*source == '\0')
{
state = oneok_state;
}else if (*source == ' ')
{
state = oneok_state;
}
else if (*source == '\n')
{
state = oneok_state;
}
else
{
state = char_state;
}
break;
case enter_state:
dest.push_back( static_cast<char> (35) );
if (*source == '\0')
{
state = end_state;
}else if (*source == ' ')
{
state = block_state;
}
else if (*source == '\n')
{
state = enter_state;
}
else
{
state = char_state;
}
break;
case oneok_state:
c = static_cast<char> ((blockNum*2 + charNum*2 + 8) * 4 + (MAX_CHAR_NUM - charNum));
//cout << (int)c << ", ";
dest.push_back( c );
charNum = 0;
blockNum = 0;
--source;
if (*source == '\0')
{
state = end_state;
}else if (*source == ' ')
{
state = block_state;
}
else if (*source == '\n')
{
state = enter_state;
}
else
{
state = char_state;
}
break;
case end_state:
break;
default:
cout << "error state from make_ShowMeString()." << endl;
break;
}
++source;
}
return dest;
}