机试-cdkey

  1. /***************************************************************** 
  2. 某软件需要实现建议的CD-KEY算法,输入3个正整数,以空格隔开,根据这3个整数生成CD-KEY字符串, 
  3. 输出格式XXXX-XXXX-XXXX-XXYY,包括16个字符,以短划线分开,其中,CD-KEY最后两个YY是用于CD-KEY的自校验,确保CD-KEY本身是合法的。 
  4. CDKEY使用的字符表23456789ABCDEFGHJKLMNPQRSTUVWXYZ 
  5. (由于1和I,0和O不好区分,删除) 
  6. 请实现CDKEY的生成算法,原理如下: 
  7. (1)输入的3个32bit的正整数,按顺序取每个整数的低16bit,假设为a,b,c串联生成一个48bit的环形,然后从低到高,每次去5个bit,并将其作为下标, 
  8. 从32字符表中取出相应字符,循环输出14个字符(提示:第一个输出的字符应该是c的低5bit生成)。 
  9. (2)上面输出14个字符即为CDKEY的从左至右的14个字符,将这14个字符按照ascii码方式全部相加,取低10bit,从低到高,查表生成两个校验位。 
  10. 样例输入: 
  11. 1 1 1 
  12. 样例输出: 
  13. 3224-2262-2A22-J2CR 
  14. *******************************************************************/  
  15. NOTE:数组的操作,细心地变量计算。
  16. C语言实现::
  17. #include<stdio.h>
    void create(unsigned int a[],char *Character,char *cdk)
    {
    	/*a[0] = a[0] & 0xffff;
    	a[1] = a[1] & 0xffff;
    	a[2] = a[2] & 0xffff;
    	*/
    	int tmp=0;
    	int i=0;
    	int j=0;
    	int b[3][16]={0};
    	int c[10]={0};
    	int pow,pos,val,sum;
    	pow=pos=val=sum=0;
    	for(i=0;i<3;i++)
    	{
    		tmp=a[2-i];
    		for(j=0;j<16;j++)
    		{
    			b[i][j]=tmp%2;
    			tmp=tmp/2;
    		}
    	}
    
    	for(i=0;i<17;i++)
    	{
    		if(i==4||i==9||i==14)
    			cdk[i++]='-';
    		for(j=0;j<5;j++)
    		{
    			if(j==0)
    				pow=1;
    			else
    				pow*=2;
    			
    			pos%=48;
    			val = b[pos/16][pos%16]*pow+val;
    			pos++;			
    		}	
    		cdk[i]=Character[val];		
    		sum +=Character[val];
    		val = 0;
    	}
    	cdk[i++]=Character[sum & 0x1f];
    	sum=sum>>5;
    	cdk[i++]=Character[sum & 0x1f];
    	cdk[i]=0;
    }
    
    int main()
    {
    	char Character[]="23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    	unsigned int a[3]={0};
    	char cdk[20]={0};
    	scanf("%d%d%d",&a[0],&a[1],&a[2]);
    	create(a,Character,cdk);
    
    	printf("%s",cdk);
    	
    }


  18. C++实现的,宿舍兄弟做的
  19. #include <iostream>
    #include <string.h>
    #include <algorithm>
    
    using namespace std;
    
    void CDKey(int* a,char* cdK,char* result)
    {
    	int d[3][16]={0};
    	
    	for(int i=0;i!=3;++i)
    	{
    		int j=0;
    		int b=a[2-i];
    		while(b)
    		{
    			d[i][j++]=b%2;
    			b=b/2;
    			if(j==16)
    				break;
    		}
    		while(j<16)
    		{
    			d[i][j++]=0;
    		}
    	}
    	int pos=0;
    	int pos_r=0;
    	int result_total=0;
    	for(int k=0;k!=14;++k)
    	{
    		
    		int value=0;
    		for(int t=0;t!=5;++t)
    		{
    			int t_v=*((int*)d+(pos+t)%48);
    			value+=t_v*pow(2,(double)t);
    		}
    		result_total+=cdK[value];
    		result[pos_r++]=cdK[value];
    		pos=(pos+5)%48;
    		if(pos_r==4 || pos_r==9 || pos_r==14)
    			result[pos_r++]='-';
    	}
    	int l=result_total&0x1F;
    	
    	int h=(result_total>>5)&0x1F;
    	result[pos_r++]=cdK[l];
    	result[pos_r++]=cdK[h];
    	result[pos_r]='\0';
    }
    
    
    void main()
    {
    	char cdK[]="23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    	int a[3];
    	cin>>a[0]>>a[1]>>a[2];
    	char result[20];
    	CDKey(a,cdK,result);
    	cout<<result<<endl;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值