1. プログラムの目的
C/C++ を使用して、次のアルゴリズムを完成させます。
文字列を入力し、その文字列の ASCII コード値の合計を確認します。値が 1000 より大きい場合、文字列は Base64 で暗号化されて出力されます。それ以外の場合、文字列は Base64 エンコード テーブルと XOR 演算されて出力されます。
2. プログラムコード
コードは以下のように表示されます。
#include<stdio.h>
#include<string.h>
int main(){
char x[1000]="",y[1000]="",z[1000]="";
char base[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int i,sum=0,len=0,j;
printf("请输入字符串:");
gets(x);
len=strlen(x);
for(i=0;i<len;i++){
sum=sum+x[i];
}
for(i=0,j=0;j<len;i+=4,j+=3){
y[i]=base[x[j]>>2];
y[i+1]=base[(x[j]&0x3)<<4|(x[j+1]>>4)];
y[i+2]=base[(x[j+1]&0xf)<<2|(x[j+2]>>6)];
y[i+3]=base[(x[j+2]&0x3f)];
}
switch(len%3){
case 1:{
y[i-2]='=';
y[i-1]='=';
break;
}
case 2:
{
y[i-1]='=';
break;
}
}
if(sum>1000){
printf("字符串的ASCII值为%d\n",sum);
printf("输入的字符串ASCII值大于1000\n");
printf("base64加密:");
puts(y);
}
else{
printf("输入的字符串ASCII值小于1000,将与base64编码表进行异或运算\n");
printf("异或运算后的结果为:");
for(i=0;i<len;i++){
z[i]=x[i]^base[i];
}
puts(z);
}
}
3. プログラムの分析
1. まず、base64 暗号化について話しましょう。
通常、1 バイトは 8 ビットであり、base64 暗号化は、これらの 8 ビットを 6 ビットにします。たとえば、「ABC」に対応するバイナリは次のようになります。
01000001 01000010 01000011
6 桁に変換すると: (010000) (010100) (001001) (000011)
正確には、最大でも 6 桁 (2 の 6 乗 = 64) しかないため、base64 はこれにちなんで名付けられ、次の表に示すように、base64 エンコード テーブルには合計 64 文字が含まれます。
上記の表を使用して、base64 で「ABC」を暗号化し、次のように取得します。 QUJD
「12」のバイナリなど、2 文字の場合: 00110001 00110010
6 桁のグループに変換すると、001100 010011 001000 (自動的に 0 を埋めるには十分ではありません)
このルールに従った元々の Base64 暗号化は次のとおりです: MTI
ただし、この種の文字列長 2%3=2 のように、「=」を追加する必要があります。つまり、最終的な暗号化結果は次のようになります: MTI=
文字列の長さが 1、つまり 1%3=1 の場合、暗号化の後に 2 つの「=」を追加する必要があります。
2. コード分析
#include<stdio.h>
#include<string.h>
int main(){
char x[1000]="",y[1000]="",z[1000]="";//初始化数组
char base[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//引入base64编码表
int i,sum=0,len=0,j;
printf("请输入字符串:");
gets(x);
len=strlen(x);//获取字符串长度
for(i=0;i<len;i++){
sum=sum+x[i];
}
このセクションは主に配列の初期化、文字列の入力、文字列の ASCII 値の計算を行います。
for(i=0,j=0;j<len;i+=4,j+=3){
y[i]=base[x[j]>>2];
y[i+1]=base[(x[j]&0x3)<<4|(x[j+1]>>4)];
y[i+2]=base[(x[j+1]&0xf)<<2|(x[j+2]>>6)];
y[i+3]=base[(x[j+2]&0x3f)];
}
switch(len%3){
case 1:{
y[i-2]='=';
y[i-1]='=';
break;
}
case 2:
{
y[i-1]='=';
break;
}
}
このセクションでは、入力文字列をbase64暗号化します。
forループ理論については何を言っていいのか分からないのでクリしかあげられません。
たとえば、ABC と入力すると、対応するバイナリは 01000001 01000010 01000011 になります。バイナリの最初のグループを 2 ビット左にシフトして、010000 とし、6 桁の基数 010000 の最初のグループを取得します。
次に、01000001 と 0x3 (つまり 11) を AND 演算し、01000001 の最後の 2 桁を取り出し、4 桁左にシフトして 010000 を取得します。これは、基数の 2 番目のグループの最初の 2 桁です。 、右にシフトします。4 桁の 01000010 (つまり、0100) を OR して、6 桁の基数 010100 の 2 番目のグループを取得します。
3 番目の基数グループは、01000010&0xf (つまり 1111) に 0010 を取得させ、次に 2 ビットを左に移動して 001000 を取得し、01000011 を 2 ビットに移動して 01、001000|01 を取得して、3 番目のグループの基数 001001 を取得します。
ベースの 4 番目のグループは 01000011&0x3f (つまり 111111) で、000011 が得られます。
「=」を追加するコードについては説明しません。栗を与えることしかできません。
たとえば、入力文字列が「1」で、for ループの後、i の値は 4、つまり y 配列の長さは 5 ですが、y[i-2] の値は空であるため、次のように追加します。 y[i-2] の '=' は値の割り当てを開始します。y[i] には格納された値がないため、配列の長さは 4 で 1%3=1 となり、これも上記のコードに準拠します (とても汚い感じですが、頑張ってQAQしました )
if(sum>1000){
printf("字符串的ASCII值为%d\n",sum);
printf("输入的字符串ASCII值大于1000\n");
printf("base64加密:");
puts(y);
}
else{
printf("输入的字符串ASCII值小于1000,将与base64编码表进行异或运算\n");
printf("异或运算后的结果为:");
for(i=0;i<len;i++){
z[i]=x[i]^base[i];
}
puts(z);
}
}
1000 を超える ASCII 値、base64 暗号化および出力
ASCII 値が 1000 未満で、元の文字列が Base64 エンコード テーブルと XOR 演算されて出力されます。
4. 実行結果と検証
プログラム実行結果:
オンラインの Base64 暗号化検証:
ASCII 値が 1000 未満で、元の文字列が Base64 エンコード テーブルと XOR 演算されて出力されます。