找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 370|回复: 2

Base64加密解密

[复制链接]

205

主题

173

回帖

6925

积分

论坛元老

积分
6925
发表于 2013-5-27 08:57:38 | 显示全部楼层 |阅读模式

Base64是网络上最常见的8bit字节代码的编码。
The Base64 Alphabet

索引

对应字符

索引

对应字符

索引

对应字符

索引

对应字符

0

A

17

R

34

i

51

z

1

B

18

S

35

J

52

0

2

C

19

T

36

K

53

1

3

D

20

U

37

L

54

2

4

E

21

V

38

M

55

3

5

F

22

W

39

N

56

4

6

G

23

X

40

O

57

5

7

H

24

Y

41

P

58

6

8

I

25

Z

42

Q

59

7

9

J

26

a

43

R

60

8

10

K

27

b

44

S

61

9

11

L

28

c

45

T

62

+

12

M

29

d

46

U

63

/

13

N

30

e

47

V



14

O

31

f

48

W



15

P

32

g

49

X



16

Q

33

h

50

Y



Base64原理:
Base64中的是我们一般的常见的可用字符,如上表所示。所以64个字符如果用二进制来表示则为26次方。所以也就是说用到了6位二进制的数可以来表示base64中的所有字符。我们可以将base64用于加密解密。那么就是将我们的一般char型的字符变为base64.字符。


编码规则:如果要将8位的char型字符变为6位的base64字符。我们可以采用如下编码规则。先将3char型字符归为一组,那么就有了24位。如果要变为6位,那么这24位字符可以变为46位的base64字符。这样依次将8位的char型字符转变为6位的base64字符。注意这里所有的转变都是以8位的char型为基础的,转变后的base64也是char型,只是其最高两位都为0。这样在后期的操作时,就可以根据上面的表格来对base64char型来赋字符了。如果还有剩余的字符那么如果来操作?一般剩余的字符就是1,2位了。
剩余为1位:这里就还有8位,如果要变为6位,那么就在它后面加40,这样变化时就可以得到26位的base64字符。为了补齐字节数,我们还要在末尾加两个=字符。剩余为2位:这里就还有16位,如果要变为6位,那么就在它后面加20,这样变化时就可以得到36位的base64字符。为了补齐字节数,我们还要在末尾加一个=字符。
做了上述操作之后,就变为4的整数倍的base64字符,实质上就最高两位都为08位二进制数。如果转换为10进制数,那么就是0~63了。如果要在系统中显示出ABCDEFGHIJKLMNOPQRSTUVWXYZabxdefghijklmnopqrstuvwxyz0123456789+/,那么就要与char型字符中的这些字符对应起来。A~Z65~90a~z97~1220~948~57+43/47。只要将这0~63变化为对应的这些字符所表示的10进制数就可以了,然后再加上相应的=字符就是我们所要的结果。
解码规则:如果要将这些加密后变为base64的字符变为原来的char型字符,这就是相当于原来的编码的逆操作了。先将显示出来的字符变为真正的base64原来的高两位都为08位二进制数。然后就可以把4base64组合起来变为3char型字符。至于剩下的字符,我这里是23位,因为我没有用到=字符来计算,只是使用了被作用后的base64字符。那么根据前面的编码理论,那么就只剩下了2位或者3base64字符了。剩下2base64,就可以解码出一位char型字符,剩下3base64字符就可以解码出2char型字符。

205

主题

173

回帖

6925

积分

论坛元老

积分
6925
 楼主| 发表于 2013-5-27 08:58:10 | 显示全部楼层
/**************************************************************
*     Copyright (C) 2006-2013 All rights reserved.
*       @Version: 1.0
*       @Created: 2013-05-19 10:40
*        @Author: chin - qin@126.com
*   @Description: 编码规则:
             1、把三上字符转换成4个字符
                例:字符串“张”
                11010101 HEX5 11000101 HEX:C5
                00110101 00011100 00010100
                十进制53 十进制34 十进制20 pad
                字符’1’ 字符’i’ 字符’U’ 字符’=
                不足的字符以'='补齐
             2、每76个字符后加一个换行符
*
*       @History:
**************************************************************/
#include <stdio.h>
#include <string.h>
#include <malloc.h>

static char base64_code_ch[64] =
{
    &#39;A&#39;,&#39;B&#39;,&#39;C&#39;,&#39;D&#39;,&#39;E&#39;,&#39;F&#39;,&#39;G&#39;,&#39;H&#39;,&#39;I&#39;,&#39;J&#39;,&#39;K&#39;,&#39;L&#39;,&#39;M&#39;,&#39;N&#39;,&#39;O&#39;,&#39&#39;,
    &#39;Q&#39;,&#39;R&#39;,&#39;S&#39;,&#39;T&#39;,&#39;U&#39;,&#39;V&#39;,&#39;W&#39;,&#39;X&#39;,&#39;Y&#39;,&#39;Z&#39;,&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;,&#39;e&#39;,&#39;f&#39;,
    &#39;g&#39;,&#39;h&#39;,&#39;i&#39;,&#39;j&#39;,&#39;k&#39;,&#39;l&#39;,&#39;m&#39;,&#39;n&#39;,&#39;o&#39;,&#39;p&#39;,&#39;q&#39;,&#39;r&#39;,&#39;s&#39;,&#39;t&#39;,&#39;u&#39;,&#39;v&#39;,
    &#39;w&#39;,&#39;x&#39;,&#39;y&#39;,&#39;z&#39;,&#39;0&#39;,&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;,&#39;+&#39;,&#39;/&#39;
};


/**
* @brief base64_to_string
*
* @Param: input
* @Param: input_len
* @Param: output_len
*
* Returns: 成功则返回解码后的字符串和长度,失败返回NULL
*/
unsigned char *base64_to_string(const unsigned char *input, size_t input_len, size_t *output_len)
{
    unsigned char *output = NULL, buf[4];
    int pos = 0;
    size_t count = 0, len = 0;

    if(input)
    {
    output = (unsigned char *)malloc(3*(input_len/4) + 1);
    if(output)
    {
        while( *input != &#39;\0&#39; )
        {
        if( *input != &#39;\n&#39; )
        {
            for(pos=0; pos < 64; pos++)
            {
            if( *input == base64_code_ch[pos])
            {
                buf[count++] = pos;
                break;
            }
            }
            if(count == 4)
            {
            output[len++] = buf[0] << 2 | buf[1] >> 4;
            output[len++] = buf[1] << 4 | buf[2] >> 2;
            output[len++] = buf[2] << 6 | buf[3];
            count = 0;
            }
            input++;
        }
        else
        {
            input++;
        }
        }
        /*处理后四位,两种情况,有一个=号和有两个=号*/
        if(count == 2)  //两个等于号的情况
        {
        output[len++] = buf[0] << 2 | buf[1] >> 4;
        }
        else if(count == 3)
        {
        output[len++] = buf[0] << 2 | buf[1] >> 4;
        output[len++] = buf[1] << 4 | buf[2] >> 2;
        }

        output[len] = &#39;\0&#39;;
        if( output_len )
        *output_len = len;

        return output;
    }
    }

    return NULL;
}

int main(int argc,char *argv[])
{
    size_t encode_len;
    size_t decode_len;
    unsigned char *p2;
    if(argc != 2)
    {
    fprintf(stderr,"Error input !\n");
    return 0;
    }
    encode_len = strlen(argv[1]);
    printf("encode_len= %u\n",encode_len);

    p2 = base64_to_string( (unsigned char *)argv[1], encode_len, &decode_len );
    //p2 = base64_to_string( NULL, encode_len, &decode_len );
    if(p2)
    printf("decode_len = %u,decode = %s\n",decode_len,p2);
    else
    printf("NULL\n");
    free(p2);
    p2 = NULL;

    return 0;
}

205

主题

173

回帖

6925

积分

论坛元老

积分
6925
 楼主| 发表于 2013-5-27 08:58:23 | 显示全部楼层
/**************************************************************
*     Copyright (C) 2006-2013 All rights reserved.
*       @Version: 1.0
*       @Created: 2013-05-19 10:40
*        @Author: chin - qin@126.com
*   @Description: 编码规则:
             1、把三上字符转换成4个字符
                例:字符串“张”
                11010101 HEX5 11000101 HEX:C5
                00110101 00011100 00010100
                十进制53 十进制34 十进制20 pad
                字符’1’ 字符’i’ 字符’U’ 字符’=
                不足的字符以&#39;=&#39;补齐
             2、每76个字符后加一个换行符
*
*       @History:
**************************************************************/
#include <stdio.h>
#include <string.h>
#include <malloc.h>

static char base64_code_ch[64] =
{
    &#39;A&#39;,&#39;B&#39;,&#39;C&#39;,&#39;D&#39;,&#39;E&#39;,&#39;F&#39;,&#39;G&#39;,&#39;H&#39;,&#39;I&#39;,&#39;J&#39;,&#39;K&#39;,&#39;L&#39;,&#39;M&#39;,&#39;N&#39;,&#39;O&#39;,&#39&#39;,
    &#39;Q&#39;,&#39;R&#39;,&#39;S&#39;,&#39;T&#39;,&#39;U&#39;,&#39;V&#39;,&#39;W&#39;,&#39;X&#39;,&#39;Y&#39;,&#39;Z&#39;,&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;,&#39;e&#39;,&#39;f&#39;,
    &#39;g&#39;,&#39;h&#39;,&#39;i&#39;,&#39;j&#39;,&#39;k&#39;,&#39;l&#39;,&#39;m&#39;,&#39;n&#39;,&#39;o&#39;,&#39;p&#39;,&#39;q&#39;,&#39;r&#39;,&#39;s&#39;,&#39;t&#39;,&#39;u&#39;,&#39;v&#39;,
    &#39;w&#39;,&#39;x&#39;,&#39;y&#39;,&#39;z&#39;,&#39;0&#39;,&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;,&#39;+&#39;,&#39;/&#39;
};


/**
* @brief string_to_base64
*
* @Param: input  输入字符串
* @Param: input_len  输入字符串长度
* @Param: out_len 编码后字符串长度
*
* Returns: 成功返回编码后的字符串,失败返回NULL
*/
unsigned char *string_to_base64(const unsigned char *input, size_t input_len, size_t *out_len )
{
    unsigned char *output = NULL;
    int i = 0;
    size_t tmp_len = 0;
    size_t len = 0;
    unsigned int count = 0;

    if(input)
    {
    tmp_len = input_len / 3;
    output = (unsigned char *)malloc( 4*(tmp_len + 1) + input_len / 76 + 1 );
    for(i=0; i < 3*tmp_len; i += 3)
    {
        output[len++] = base64_code_ch[input >> 2];
        output[len++] = base64_code_ch[(input & 0x03) << 4 | input[i + 1] >> 4];
        output[len++] = base64_code_ch[(input[i + 1] & 0x0F) << 2 | input[i + 2] >> 6];
        output[len++] = base64_code_ch[input[i + 2] & 0x3F];
        count++;
        if( count % 19 == 0)
        {
        output[len++] = &#39;\n&#39;;
        count = 0;
        }
    }
    /*分开做,为了简洁可读性*/
    tmp_len = input_len % 3;
    if(tmp_len != 0)
    {
        if(tmp_len == 1)
        {
        output[len++] = base64_code_ch[input >> 2];
        output[len++] = base64_code_ch[(input & 0x03) << 4];
        output[len++] = &#39;=&#39;;
        output[len++] = &#39;=&#39;;
        count++;
        }
        else
        {
        output[len++] = base64_code_ch[input >> 2];
        output[len++] = base64_code_ch[(input & 0x03) << 4 | input[i + 1] >> 4];
        output[len++] = base64_code_ch[(input[i + 1] & 0x0F) << 2];
        output[len++] = &#39;=&#39;;
        count++;
        }
    }
    if( count % 19 == 0)
    {  
        output[len++] = &#39;\n&#39;;
    }
    output[len] = &#39;\0&#39;;
    /*返回编码后的长度和字符串*/
    if(out_len)
        *out_len = len;
    return output;
    }

    return NULL;
}


int main(int argc,char *argv[])
{
    size_t encode_len;
    size_t src_len;
    unsigned char *p1;

    if(argc != 2)
    {
    fprintf(stderr,"Error input !\n");
    return 0;
    }
    src_len = strlen(argv[1]);
    printf("src_len = %u\n",src_len);
    p1 = string_to_base64( (unsigned char *)argv[1], src_len, &encode_len );
    if(p1)
    printf("encode_len = %u,encode = %s\n",encode_len,p1);

    free(p1);
    p1 = NULL;

    return 0;
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-1 21:04 , Processed in 0.084952 second(s), 20 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表