golang 自行实现一个base64加密
2023-03-10 14:16 dribs 阅读(110) 评论(0) 编辑 收藏 举报package main import ( "fmt" "strconv" ) const base64table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" func Mybase64(a string) { //定义一个byte数组 放要base64的字符 d := []byte(a) //定义一个string 放解析的二进制 var s string //定义补余个数用于最后==计算 var buyu int //取模,3个一断,每个8个位 共24位,跟base64 6位一断,刚好凑4个。 if len(d)%3 != 0 { //计算要补多少个字符的0,不够三个字符的用0 补上去 buyu = 3 - len(d)%3 for i := 0; i < buyu; i++ { d = append(d, 0) } } //把要base64的字符转成一长串二进制,用于6个一断 for _, b := range d { s += fmt.Sprintf("%08b", b) } //6个一断 j := 6 //不写if 定义字典存放 补余的几个= buyumap := map[int]string{1: "=", 2: "=="} var ret string for i := 0; i < len(s); i += 6 { s := fmt.Sprintf("0b%s", s[i:j]) j += 6 b, _ := strconv.ParseInt(s[2:], 2, 32) fmt.Printf("%s===>%d==base64==>%s\n", s, b, string(base64table[b])) ret += fmt.Sprintf(string(base64table[b])) } s2 := ret[0 : len(ret)-buyu] s3 := fmt.Sprintf("%s%s", s2, buyumap[buyu]) fmt.Println(s3) } func main() { Mybase64("123a45671") //data := []byte("123a45671") //dst := make([]byte, base64.StdEncoding.EncodedLen(len(data))) //base64.StdEncoding.Encode(dst, data) //fmt.Println(string(dst)) }
以下为chatGPT的回答解析,参考理论是对的,个别值解释的不对
当我们将字符串"abcd"转换成对应的ASCII码值时,得到97、98、99、100。然后将这四个值按照每3个一组进行分组,得到(97, 98, 99),(100)。 接着,将每组3个字节的数据拆分成4个6位的二进制数,这里以第一组为例: 第1个字节:97,对应的二进制数为 01100001 第2个字节:98,对应的二进制数为 01100010 第3个字节:99,对应的二进制数为 01100011 将这3个二进制数拼接在一起,得到24位的二进制数:01100001 01100010 01100011。 然后将这个24位的二进制数分成4个6位的二进制数: 第1个6位二进制数:011000,对应的十进制数为 24,Base64字符集中对应的字符为 'Y'。 第2个6位二进制数:010110,对应的十进制数为 22,Base64字符集中对应的字符为 'W'。 第3个6位二进制数:001100,对应的十进制数为 12,Base64字符集中对应的字符为 'M'。 第4个6位二进制数:000001,对应的十进制数为 1,Base64字符集中对应的字符为 'B'。 对于第二组(100),因为只有一个字节,所以需要在末尾添加两个字节值为0的字节,得到(100, 0, 0)。 将这三个字节拼接在一起,得到16位的二进制数:01100100 00000000 00000000。 然后将这个16位的二进制数分成3个6位的二进制数和1个填充字符: 第1个6位二进制数:011001,对应的十进制数为 25,Base64字符集中对应的字符为 'Z'。 第2个6位二进制数:000000,对应的十进制数为 0,Base64字符集中对应的字符为 'A'。 第3个6位二进制数:000000,对应的十进制数为 0,Base64字符集中对应的字符为 'A'。 第一个填充字符:'=' 最后,将这4个Base64字符拼接在一起,得到"YWJjZA== ",这就是字符串"abcd"的Base64编码结果