the cryptopals crypto challenges学习记录(一)

the cryptopals crypto challenges学习记录(一)

目录

  • the cryptopals crypto challenges学习记录(一)
  • 前言
  • 简单介绍base64
  • set1 challenge1
    • python实现(附带10进制转base64):
    • C++实现
  • 介绍异或
  • set1 challenge2
    • python实现


前言

第一次手写base64解密和异或


简单介绍base64

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。

the cryptopals crypto challenges学习记录(一)_第1张图片
以给aa进行base编码为例:

aa的二进制为:01100001 01100001

分成6位一组:011000 010110 000100(最后两个是补上的0)

转为10进制:24 22 4

查表,转为base64,为:Y W E =(=是填充上的)

set1 challenge1

the cryptopals crypto challenges学习记录(一)_第2张图片

python实现(附带10进制转base64):

代码如下:

#16进制转base64 python

from enum import Enum
b64_encode = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

class abc(Enum):#定义一个类 包含3种情况
    one = 0
    two = 1#需要填充2bit
    four = 2#需要填充4bit
def hex_to_base64(hexdata):
    b64data = ""
    sixbits = 0
    ab = abc.one
    for hexchar in hexdata:
        dec = int(hexchar, 16)#把16进制字符转为对应的十进制字符
        if ab == abc.one:
            sixbits = dec
            ab = abc.two
#如果是新的一组.将一个16进制字符的4位放入
#那么还需要两个bit进行填充.接着将ab设置为填充2位的情况
        elif ab == abc.two:
            sixbits = (sixbits << 2) | (dec >> 2)
            b64data += b64_encode[sixbits]
            sixbits = (dec & 0x3) #0x3 is 0x11
            ab = abc.four
#如果需要填充2位,则填充后该组就完整了,就可以通过编码表进行对应编码了
#编码后将其附加到编码后字符串末尾.接着将ab设置为填充4位的情况
        elif ab == abc.four:
            sixbits = (sixbits << 4) | dec
            b64data += b64_encode[sixbits]
            ab = abc.one
#如果需要填充4位,则填充后该组就完整了,就可以通过编码表进行对应编码了
#编码后将其附加到编码后字符串末尾.接着将status设置为处理新一组的情况
    if ab == abc.two:
        sixbits <<= 2
        b64data += b64_encode[sixbits]
        b64data += "="
    elif ab == abc.four:
        sixbits <<= 4
        b64data += b64_encode[sixbits]
        b64data += "=="

    return b64data
def main():
    cc=hex_to_base64('49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d')
    print(cc)

if __name__ == '__main__':
    main()
#---------------------------------------------------------------
#10进制转base64
def base64(str):
    ret = bytearray("",encoding="utf-8")# 定义一个bytearray 类型,可以修改的byte类型
    length = len(str)
    r = 0# 记录补 0 个数,之后会替换为 =
    for x in range(0,length,3):
        if x+3 <= length: #判断是否满足凑够三个字节,能凑够三个字节,则计算,不能凑够则补0
            y = str[x:x+3]
        else:
            y = str[x:]
            r = 3-len(y)# 计算补0的个数
            y = y + "\x00"*r
        a = int.from_bytes(y.encode(), "big") # 大端对齐
        for i in range(18, -1, -6):
            if i == 18:
                index = a >> i # 6个bit,6个bit一起
            else:
                index = a >> i & 0x3f##0011 1111
            ret.append(alphabet[index]) # 最佳Base64 编码
        for i in range(1,r+1):
            ret[-i] = 0x3D ##不够的部分补 =
    return ret

if __name__ == "__main__":
    alphabet = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    #base64编码表
    str = input()
    print(base64(str).decode("utf-8"))




输出结果:

在这里插入图片描述


C++实现

代码如下:

#include
using namespace std;
struct twoandsixteen
{
     
    int c[4];//二进制
    char b;//对应十六进制字符
};
struct base64
{
     
    int t[6];//6bit
    int x;
    char d;
};
struct bas64a
{
     
    int p;//base64编码的值
    char q;//base64编码值对应的字符
};
int main()
{
     
        struct twoandsixteen sss[16]={
     
            {
     {
     0,0,0,0},'0'},
            {
     {
     0,0,0,1},'1'},
            {
     {
     0,0,1,0},'2'},
            {
     {
     0,0,1,1},'3'},
            {
     {
     0,1,0,0},'4'},
            {
     {
     0,1,0,1},'5'},
            {
     {
     0,1,1,0},'6'},
            {
     {
     0,1,1,1},'7'},
            {
     {
     1,0,0,0},'8'},
            {
     {
     1,0,0,1},'9'},
            {
     {
     1,0,1,0},'a'},
            {
     {
     1,0,1,1},'b'},
            {
     {
     1,1,0,0},'c'},
            {
     {
     1,1,0,1},'d'},
            {
     {
     1,1,1,0},'e'},
            {
     {
     1,1,1,1},'f'}
        };
        struct bas64a www[64]={
     
            {
     0,'A'},{
     1,'B'},{
     2,'C'},{
     3,'D'},{
     4,'E'},{
     5,'F'},{
     6,'G'},{
     7,'H'},{
     8,'I'},{
     9,'J'},
            {
     10,'K'},{
     11,'L'},{
     12,'M'},{
     13,'N'},{
     14,'O'},{
     15,'P'},{
     16,'Q'},{
     17,'R'},{
     18,'S'},{
     19,'T'},
            {
     20,'U'},{
     21,'V'},{
     22,'W'},{
     23,'X'},{
     24,'Y'},{
     25,'Z'},{
     26,'a'},{
     27,'b'},{
     28,'c'},{
     29,'d'},
            {
     30,'e'},{
     31,'f'},{
     32,'g'},{
     33,'h'},{
     34,'i'},{
     35,'j'},{
     36,'k'},{
     37,'l'},{
     38,'m'},{
     39,'n'},
            {
     40,'o'},{
     41,'p'},{
     42,'q'},{
     43,'r'},{
     44,'s'},{
     45,'t'},{
     46,'u'},{
     47,'v'},{
     48,'w'},{
     49,'x'},
            {
     50,'y'},{
     51,'z'},{
     52,'0'},{
     53,'1'},{
     54,'2'},{
     55,'3'},{
     56,'4'},{
     57,'5'},{
     58,'6'},{
     59,'7'},
            {
     60,'8'},{
     61,'9'},{
     62,'+'},{
     63,'/'}
        };
        struct twoandsixteen a[10000];
        int n=0;
        while(a[n].b=getchar())//逐个输入要加密的字符并记录位数
        {
     
            if(a[n].b=='\n') break;
            n=n+1;
        }
        for(int h=0;h<n;h++)//拷贝操作,将输入字符串对应的二进制拷贝入a[]中
        {
     
            for(int e=0;e<16;e++)
            {
     
                if(a[h].b==sss[e].b)
                {
     
                    a[h].c[0]=sss[e].c[0];
                    a[h].c[1]=sss[e].c[1];
                    a[h].c[2]=sss[e].c[2];
                    a[h].c[3]=sss[e].c[3];
                }
            }
        }

        int w[4*n],z=0;

        for(int h=0;h<4*n+4;h=h+4)//将a[]中数据拷贝到w[]中  可用函数处理
        {
     
            w[h]=a[z].c[0];
            w[h+1]=a[z].c[1];
            w[h+2]=a[z].c[2];
            w[h+3]=a[z].c[3];
            z=z+1;
        }

        struct base64 y[(4*n)/6];//6bit
        int m=0;

        for(int h=0;h<(4*n)/6;h++)//把w[]中的0,1进行划分,6个一组
        {
     
            int n1=0;
            for(int e=m;e<m+6;e++)
            {
     
                y[h].t[n1]=w[e];
                n1=n1+1;
            }
            m=m+6;
        }

        for(int h=0;h<(4*n)/6;h++)//把划分后的二进制转化位10进制
        {
     
            y[h].x=y[h].t[0]*32+y[h].t[1]*16+y[h].t[2]*8+y[h].t[3]*4+y[h].t[4]*2+y[h].t[5]*1;
        }

        for(int h=0;h<(4*n)/6;h++)//根据转化后的10进制找对应的base64编码
        {
     
            for(int e=0;e<64;e++)
            {
     
                if(y[h].x==www[e].p) y[h].d=www[e].q;
            }
        }

        for(int h=0;h<(4*n)/6;h++)//将编码输出
        {
     
            cout<<y[h].d;
        }

        if(((4*n)%6)==2)//如果余数为2后边补0,补足6位
        {
     
            int k=w[4*n-2]*32+w[4*n-1]*16;
            for(int e=0;e<64;e++)
            {
     
                if(k==www[e].p) cout<<www[e].q;
            }
            cout<<"=";
        }
        else if(((4*n)%6)==4)//如果余数为4后边补0,补足6位
        {
     
            int k=w[4*n-4]*32+w[4*n-3]*16+w[4*n-2]*8+w[4*n-1]*4;
            for(int e=0;e<64;e++)
            {
     
                if(k==www[e].p) cout<<www[e].q;
            }
            cout<<"=";
        }

        cout<<endl;
        //system("pause");
        return 0;
}


在这里插入图片描述


介绍异或

the cryptopals crypto challenges学习记录(一)_第3张图片
the cryptopals crypto challenges学习记录(一)_第4张图片
the cryptopals crypto challenges学习记录(一)_第5张图片

异或:异或运算符”∧” 。参加运算的两个二进位同号,则结果为0(假);异号则为1(真)。即 0∧0=0,0∧1=1, 1^0=1,1∧1=0。

异或的运算:先转化为二进制,再对照位来进行运算,相同为0,不同为1。
通过按位异或运算,可以实现两个值的交换,而不必使用临时变量。例如交换两个整数a=3,b=4的值,可通过下列语句实现:

a=a∧b
b=b∧a
a=a∧b


set1 challenge2

the cryptopals crypto challenges学习记录(一)_第6张图片


python实现

def hex_xor (hexdata1, hexdata2):
    a1 = int(hexdata1, 16)
    a2 = int(hexdata2, 16)
    xor1 = a1 ^ a2
    return hex(xor1)[2:]
def main():
    a = hex_xor("1c0111001f010100061a024b53535009181c686974207468652062756c6c277320657965")
    print(a)
if __name__ == '__main__':
    main()

结果:

在这里插入图片描述


参考文献:
base64
异或

你可能感兴趣的:(cryptopals,crypto,challenges,python,c++)