欢迎光临散文网 会员登陆 & 注册

给@蕾米莉亞_斯卡雷特的代码演示

2022-05-23 22:47 作者:darkblueu  | 我要投稿

@蕾米莉亞_斯卡雷特的代码演示

对于av号转bv号/bv号转av号 c语言一文中的代码

如何用30行代码实现几乎相同的功能

#include<stdio.h>

#include<stdlib.h>

int to_a[256],to_b[256],check_res,order[]= {9,8,1,6,2,4,0,7,3,5},data[]={13,12,46,31,43,18,40,28,5,54,20,15,8,39,57,45,36,38,51,42,49,52,53,7,4,9,50,10,44,34,6,25,1,26,29,56,3,24,0,47,27,22,41,16,11,37,2,35,21,17,33,30,48,23,55,32,14,19};

char input[13],cset[] ={"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"};

int is_digit(char *s) {

for(char* ss=s; *ss; ss++)if('0'>*ss||*ss>'9')return 0;

return 1;

}//判断是不是纯数字(av号) 

unsigned long long B_to_A(char* s) {

unsigned long long sum = 0;

for(int i=9; i>=0; i--)sum*=58,sum+=to_a[s[order[i]]];//order控制顺序 

return (sum-100618342136696320)^0xa93b324;//这个异或等价于那十几行零一串的代码 

}//转化为av号的等价代码

char* A_to_B(char* s) {

unsigned long long  av = (strtoull(s,NULL,10)^0xa93b324)+100618342136696320;

for(int i=0; i<10; i++)s[order[i]]=to_b[av%58],av/=58;//直接和上面反过来 

return s;

}//转化为Bv号的等价代码 

int main() {

for(int i=0; i<58; i++) {

to_a[cset[i]] = data[i];

to_b[data[i]] = cset[i];//直接用数组索引建立双射 

}

printf("请输入av/bv号:");

gets(input);//这里有一点不同的是,要求格式必须正确,然后去掉前两个字母 

if(!is_digit(input+2))printf("您输入的bv号所对应的av号是:av%llu",B_to_A(input+2));

else printf("您输入的av号所对应的bv号是:BV%s",A_to_B(input+2));

}

        这里提出几个思想,一是用数组保存加密的结果,建立映射,用索引直接访问,避免使用函数遍历(其实这样也更快了),然后个数位转换和顺序可以通过简单逻辑和循环实现。对于无符号长整形可以直接使用位运算(异或运算)以避免转化成二进制。

        如果加入安全输入,即判断输入的格式是否合法,代码会变成60行(其实基本功能也就十多行,大部分还是输入和判断)。

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<ctype.h>

const int len = 58;

int to_a[256],to_b[256],check_res,order[]= {9,8,1,6,2,4,0,7,3,5},

        data[]= {13,12,46,31,43,18,40,28,5,54,20,15,8,39,57,45,36,38,51,42,49,52,53,7,4,9,50,10,44,34,6,25,1,26,29,56,3,24,0,47,27,22,41,16,11,37,2,35,21,17,33,30,48,23,55,32,14,19};

char input[13],cset[] = {"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"};

int is_digit(char *s) {

    for(char* ss=s; *ss; ss++)if(!isdigit(*ss))return 0;

return 1;

}

int is_Bv(char *s) {

for(char* ss=s; *ss; ss++)if(!to_a[*ss])return 0;return 1;

}

int checkavOrBv(char* s) {

if(!*s)return -1;

char hat[13];

strncpy(hat,s,2);

strupr(hat);

if(!strcmp(hat,"av")) {

strcpy(s,s+2);

return is_digit(s)?1:-1;

} else if(!strcmp(hat,"BV")) {

strcpy(s,s+2);

return is_Bv(s)?0:-1;

} else return is_digit(s)?1:is_Bv(s)?0:-1;

}

unsigned long long B_to_A(char* s) {

unsigned long long sum = 0;

for(int i=9; i>=0; i--)sum*=len,sum+=to_a[s[order[i]]];

return (sum-100618342136696320)^0xa93b324;

}

char* A_to_B(char* s) {

unsigned long long  av = (strtoull(s,NULL,10)^0xa93b324)+100618342136696320;

printf("%llu",strtoull(s,NULL,10));

for(int i=0; i<10; i++)s[order[i]]=to_b[av%len],av/=len;s[10]=0;

return s;

}

int main() {

for(int i=0; i<len; i++) {

to_a[cset[i]] = data[i];

to_b[data[i]] = cset[i];

}

printf("请输入av/bv号:");

while(true) {

gets(input);

if((check_res=checkavOrBv(input))==-1) {

printf("你输入的格式不正确,请重新输入:");

continue;

} else if(check_res==0)printf("您输入的bv号所对应的av号是:av%llu",B_to_A(input));

else printf("您输入的av号所对应的bv号是:BV%s",A_to_B(input));

break;

}

}

在av号超过0xFFFFFFF(十六进制)后两者结果会不一样,是正常现象,现在的av号也不会超过这个值。至于为什么不一样,可以自己思考一下。

给@蕾米莉亞_斯卡雷特的代码演示的评论 (共 条)

分享到微博请遵守国家法律