加密解密演算法系列

Re_Upper 發表於 2022-06-09
演算法 加密

z3

語法

1
https://z3prover.github.io/api/html/classz3py_1_1_solver.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from z3 import *
x = Real('x')
y = Real('y')      #設未知數
 
s = Solver()       #建立約束求解器
 
s.add(30*x+15*y==675)
s.add(12*x+5*y==265)    #新增約束條件
 
if s.check() == sat:    #檢測是否有解
    result = s.model()  
    print result        #若有解則得出解,注意這裡的解是等式
else:  
    print 'no result'     #無解則列印no result
1
2
X =  [BitVec(('x%s' % i),8) for i in range(0x22) ]  
# “x%s”%i返回一個字串,其中%s被i替代

單向雜湊演算法

也稱之為雜湊演算法,將任意長度的訊息壓縮到某一固定的長度的函式

MD5

對輸入的任意長度進行運算,產生一個128位的摘要

 

演算法原理

 

(1)資料填充:

 

填充的方法是填充一個1和n個0。

 

使得

 

len%512=512-64=448

 

你的長度-448是512的倍數

 

(2),記錄資訊長度

 

之前我們有len%512=512-64=448

 

現在用64位來儲存填充前資訊長度。這樣資訊長度就變為

 

real_len=N*512+448+64=(N+1)*512位

 

(3)裝入標準的幻數(四個整數)

 

標準的幻數(物理順序)

 

A=(01234567) 16 ,

 

B=(89ABCDEF) 16 ,

 

C=(FEDCBA98) 16 ,

 

D=(76543210) 16 。

 

如果在程式中定義應該(A=0x67452301L,B=0xEFCDAB89L,C=0x98BADCFEL,D=0x10325476L)。有點暈哈,其實想一想就明白了

 

(4)四輪迴圈運算:

 

迴圈的次數是分組的個數(N+1)

base

base16

encode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h>
#include<string.h>
 
int main(void)
{
    char input[100] = "dqx-0x9d";
    char encode[100]={0};
 
    unsigned char table[17] = "0123456789ABCDEF";//我們可以修改這個表格
    int len_input, len_code, i, ii, num;
    len_input = strlen(input);
 
    len_code = len_input * 2;
 
    for (i = 0, ii = 0; i < len_input; i++, ii += 2)
    {
        encode[ii]      = table[input[i] >> 4];//4位 ,            我們可以修改bit位
        encode[ii + 1= table[input[i] & 0b00001111];//4
    }
 
    printf("%d:%d\n",len_input,len_code);
    printf("%s:%s\n",input,encode);
}

decode

爆破指令碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<stdio.h>
#include<string.h>
 
int main(void)
{
    //
 
    char input[]="6471782D30783964";
 
    char table[]="0123456789ABCDEF";
    int len=strlen(input);
    unsigned int i = 0, ii = 0;
    unsigned char flag1=0;
    for (; i < len/2; i++, ii += 2)
    {
        for(flag1=0;flag1<128;flag1++)
        {
            if( table[flag1>>4]==input[ii]             \
                                                &&     \
                table[flag1&15]==input[ii+1]
              )
              {
                  printf("%c",flag1);
                  break;
              
        }
    }
}

方法一,直接獲取在table中的表,然後計算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<stdio.h>
#include<string.h>
 
int main(void)
{
 
 
    char table[17] = "0123456789ABCDEF";//
 
    char encode[]="6261636465";
    char decode[100]={0};
 
    unsigned int index[100]={0};
    unsigned int i=0,ii=0;
    for(i=0;i<strlen(encode);i++)
        for(ii=0;ii<strlen(table);ii++)
            if(encode[i]==table[ii])
                index[i]=ii;
    for(i=0,ii=0;i<strlen(encode)/2;i++,ii+=2)
        decode[i]=(index[ii]<<4)|index[ii+1];
    puts(decode);
    return 0;
}
/*
找到在表中的位置 ,每2個為一個位置
index1  高4位 ,左移動4
index2  低4位,取滴4
 相或
*/

方法二

 

根據已經有的表去獲取它的index

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<stdio.h>
#include<string.h>
 
int main(void)
{
    char encode[100] = "6471782D30783964";
    char decode[100];
    int  table['F'+1] = {0,0,0,0,    0,0,0,0,    0,0,0,0,    0,0,0,0, //16
                         0,0,0,0,    0,0,0,0,    0,0,0,0,    0,0,0,0, //32
                         0,0,0,0,    0,0,0,0,    0,0,0,0,    0,0,0,0, //48
                         0,1,2,3,    4,5,6,7,    8,9,0,0,    0,0,0,0, //64
                         0,10,11,    12,13,14,   15
    };
 
    int len_decode, len_encode, ii, i;
 
    len_encode = strlen(encode);
    len_decode = len_encode / 2;
 
    for (ii = 0, i = 0; ii < len_encode; ii += 2, i++)
        decode[i] = table[encode[ii]] << 4 | table[encode[ii + 1]];
    for (ii = 0; ii < len_decode; ii++)
        printf("%c", decode[ii]);
 
}

base32

圖片描述

 

encode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<stdio.h>
#include<string.h>
int main(int argc, char* argv[])
{
    char S_[100] = "dqx-0x9d";
    char D_[100]={0};
    unsigned char table[33] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
    int len_input, encode_len, i, j, redundant;
    int base;
 
    len_input = strlen(S_);
 
    //  現在的長度是8/5
 
    if (len_input % 5 != 0)//滿足是5的倍數
        encode_len = (len_input / 5 + 1) * 8;
    else
        encode_len = (len_input / 5) * 8;
    base = encode_len - 8;
 
    for (i = 0, j = 0; j < encode_len; i += 5, j += 8)//針對5個去處理,8個去接收
    {
        D_[j] = table[S_[i] >> 3];
        D_[j + 1] = table[((S_[i] & 7) << 2) | (S_[i + 1] >> 6)];
        D_[j + 2] = table[(S_[i + 1] >> 1) & 31];
        D_[j + 3] = table[(S_[i + 1] & 1) << 4 | S_[i + 2] >> 4];
        D_[j + 4] = table[(S_[i + 2] & 15) << 1 | S_[i + 3] >> 7];
        D_[j + 5] = table[(S_[i + 3] >> 2) & 31];
        D_[j + 6] = table[(S_[i + 3] & 3) << 3 | S_[i + 4] >> 5];
        D_[j + 7] = table[S_[i + 4] & 31];
    }
    redundant = len_input % 5;//末尾補上幾個=
    switch (redundant)
    {
    case 1:
        i = 2;break;
    case 2:
        i = 4;break;
    case 3:
        i = 5;break;
    case 4:
        i = 7;break;
    }
    for (; i < 8; i++)
        D_[base + i] = '=';
    printf("%s \n %s\n", S_, D_);
}