the cryptopals crypto challenges学习记录(一)

the cryptopals crypto challenges学习记录(一)


前言

第一次手写base64解密和异或


简单介绍base64

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

在这里插入图片描述
以给aa进行base编码为例:

aa的二进制为:01100001 01100001

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

转为10进制:24 22 4

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

set1 challenge1

在这里插入图片描述

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<bits/stdc++.h>
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;
}


在这里插入图片描述


介绍异或

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

异或:异或运算符”∧” 。参加运算的两个二进位同号,则结果为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

在这里插入图片描述


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
异或

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值