# Common Encryption Algorithms and Code Recognition

EN | ZH

## Base64¶

Base64 是一种基于64个可打印字符来表示二进制数据的表示方法。转换的时候，将3字节的数据，先后放入一个24位的缓冲区中，先来的字节占高位。数据不足3字节的话，于缓冲器中剩下的比特用0补足。每次取出6比特（因为 ），按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出，直到全部输入数据转换完成。

## Tea¶

#include <stdint.h>

void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */
uint32_t delta=0x9e3779b9;                     /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
for (i=0; i < 32; i++) {                       /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
}                                              /* end cycle */
v[0]=v0; v[1]=v1;
}

void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */
uint32_t delta=0x9e3779b9;                     /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
for (i=0; i<32; i++) {                         /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
}                                              /* end cycle */
v[0]=v0; v[1]=v1;
}


## RC4¶

void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函数
{
int i =0, j = 0;
char k[256] = {0};
unsigned char tmp = 0;
for (i=0;i<256;i++) {
s[i] = i;
k[i] = key[i%Len];
}
for (i=0; i<256; i++) {
j=(j+s[i]+k[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[i]和s[j]
s[j] = tmp;
}
}

void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for(k=0;k<Len;k++) {
i=(i+1)%256;
j=(j+s[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[x]和s[y]
s[j] = tmp;
t=(s[i]+s[j])%256;
Data[k] ^= s[t];
}
}


  for i from 0 to 255
S[i] := i
endfor
j := 0
for( i=0 ; i<256 ; i++)
j := (j + S[i] + key[i mod keylength]) % 256
swap values of S[i] and S[j]
endfor


 i := 0
j := 0
while GeneratingOutput:
i := (i + 1) mod 256   //a
j := (j + S[i]) mod 256 //b
swap values of S[i] and S[j]  //c
k := inputByte ^ S[(S[i] + S[j]) % 256]
output K
endwhile


## MD5¶

MD5消息摘要算法（英语：MD5 Message-Digest Algorithm），一种被广泛使用的密码散列函数，可以产生出一个128位（16字节）的散列值（hash value），用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特（Ronald Linn Rivest）设计，于1992年公开，用以取代MD4算法。这套算法的程序在 RFC 1321 中被加以规范。

/Note: All variables are unsigned 32 bits and wrap modulo 2^32 when calculating
var int[64] r, k

//r specifies the per-round shift amounts
r[ 0..15]：= {7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22}
r[16..31]：= {5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20}
r[32..47]：= {4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23}
r[48..63]：= {6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21}

//Use binary integer part of the sines of integers as constants:
for i from 0 to 63
k[i] := floor(abs(sin(i + 1)) × 2^32)

//Initialize variables:
var int h0 := 0x67452301
var int h1 := 0xEFCDAB89
var int h3 := 0x10325476

//Pre-processing:
append "1" bit to message
append "0" bits until message length in bits ≡ 448 (mod 512)
append bit length of message as 64-bit little-endian integer to message

//Process the message in successive 512-bit chunks:
for each 512-bit chunk of message
break chunk into sixteen 32-bit little-endian words w[i], 0 ≤ i ≤ 15

//Initialize hash value for this chunk:
var int a := h0
var int b := h1
var int c := h2
var int d := h3

//Main loop:
for i from 0 to 63
if 0 ≤ i ≤ 15 then
f := (b and c) or ((not b) and d)
g := i
else if 16 ≤ i ≤ 31
f := (d and b) or ((not d) and c)
g := (5×i + 1) mod 16
else if 32 ≤ i ≤ 47
f := b xor c xor d
g := (3×i + 5) mod 16
else if 48 ≤ i ≤ 63
f := c xor (b or (not d))
g := (7×i) mod 16

temp := d
d := c
c := b
b := leftrotate((a + f + k[i] + w[g]),r[i]) + b
a := temp
Next i
//Add this chunk's hash to result so far:
h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
End ForEach
var int digest := h0 append h1 append h2 append h3 //(expressed as little-endian)


    h0 = 0x67452301;
h1 = 0xefcdab89;