golang base64解码

解码过程

1.使用标准库的base64.StdEncoding.DecodeString

  最开始是印象标准库有一个base64.StdEncoding.DecodeString方法可以解码,就直接使用了这个方法

package main
 
import(
    "encoding/base64"
    "fmt"
)
 
func main(){
    encrypt := "Cf1WA2nBMo3H9G2UPhlLBBVBsMDl4udWr7__e6Iy93eIqLKi3EOjGhk8TkHujL1Uj6aGfZJNBzIbVE2NfNaz4pob8uiQvGaeTZdWP-8lFmAm6J1sz8N15xQkO7ADa5bNLCCqtlQbN2z7JcNenvFuID_rZGqb_1gmr-BGubGRMiMSK7RdjQYrMHaBcHLPB0UteakzcQwgKxCW7u0ECHqPJ39ne9JUG22JBWRo1ORuX5r30J_XrW3SQcdPSxfe0kvd61y12QOYh8VlOBBdBeDNnyDXefI_tDJDBFeqTXCgKu9wFkkWIZiM7WwqogaY-bvjUisbrPO4_fjJ1c0nWDOqRA"
    _,err := base64.StdEncoding.DecodeString(encrypt)
    if err != nil {
        fmt.Println(err)
    }
}

执行结果

illegal base64 data at input byte 34

解码报错了,根据提示意思大概能猜到是第34位的字符‘_’ base64不认识,去查了下base64的索引表

 发现base64的字符集内没有我们第34位对应的字符‘_’,当时想是不是做了类似urlencode的编码,防止http传输过程中部分字符转义,继续查base64文档发现了 如下一段内容

 可以确定是将+和/分别改成了-和_, 那我们应该做一下字符串替换把-和_改回来就行,本来想直接在代码里面写字符串替换,后来想GO标准库还没细看,里面是不是还有现成的方法之前没发现,查了下标准库发现

 URLEncoding和我们刚用的StdEncoding有一些区别,是用于URL和文件名,刚我们碰到的问题也是URL问题

2.用base64.URLEncoding.DecodeString方法尝试

  经过了上一步的测试和文档查找,感觉用这个方法应该就可以搞定问题了,赶紧写个测试看看

package main
 
import(
    "encoding/base64"
    "fmt"
)
 
func main(){
    encrypt := "Cf1WA2nBMo3H9G2UPhlLBBVBsMDl4udWr7__e6Iy93eIqLKi3EOjGhk8TkHujL1Uj6aGfZJNBzIbVE2NfNaz4pob8uiQvGaeTZdWP-8lFmAm6J1sz8N15xQkO7ADa5bNLCCqtlQbN2z7JcNenvFuID_rZGqb_1gmr-BGubGRMiMSK7RdjQYrMHaBcHLPB0UteakzcQwgKxCW7u0ECHqPJ39ne9JUG22JBWRo1ORuX5r30J_XrW3SQcdPSxfe0kvd61y12QOYh8VlOBBdBeDNnyDXefI_tDJDBFeqTXCgKu9wFkkWIZiM7WwqogaY-bvjUisbrPO4_fjJ1c0nWDOqRA"
    _,err := base64.URLEncoding.DecodeString(encrypt)
    if err != nil {
        fmt.Println(err)
    }
}

执行一下 又报错了,心累,看了下错误信息illegal base64 data at input byte 340,跟第一步报错的大致一样只是最后的位置变到了340,说明我们前面转义的问题用这个方法还是解决了,但是执行到最后的时候又有不标准字符了,继续查base64的文档,又有新发现,如图

 大致意思是,如果编码的时候字节不足会在最后加一到两个=号,但看我们的字符串最后没有=,解码的时候解到最后又报错了,赶紧给字符串手动加个等号试试

package main
 
import(
    "encoding/base64"
    "fmt"
)
 
func main(){
    encrypt := "Cf1WA2nBMo3H9G2UPhlLBBVBsMDl4udWr7__e6Iy93eIqLKi3EOjGhk8TkHujL1Uj6aGfZJNBzIbVE2NfNaz4pob8uiQvGaeTZdWP-8lFmAm6J1sz8N15xQkO7ADa5bNLCCqtlQbN2z7JcNenvFuID_rZGqb_1gmr-BGubGRMiMSK7RdjQYrMHaBcHLPB0UteakzcQwgKxCW7u0ECHqPJ39ne9JUG22JBWRo1ORuX5r30J_XrW3SQcdPSxfe0kvd61y12QOYh8VlOBBdBeDNnyDXefI_tDJDBFeqTXCgKu9wFkkWIZiM7WwqogaY-bvjUisbrPO4_fjJ1c0nWDOqRA"
    //为了不修改原字符串,没有直接在原字符串上追加
    encrypt = fmt.Sprint(encrypt,"==")
    _,err := base64.URLEncoding.DecodeString(encrypt)
    if err != nil {
        fmt.Println(err)
    }
}
View Code

加了两个等号,居然解码成功了,太不容易了,但是这问题也来了, 这追加的等号也不是固定的,如果在代码里面判断增加也很不方便啊,刚尝到查GO文档的好处了,带着问题找一个可以忽略最后等号的方法,看下GO文档里有没有,

3.使用base64.RawURLEncondig.DecodeString

前一个步骤我们得到的结论要在GO文档中找一个可以将-_还原成base64字符的同时可以让我们忽略末尾=号的,嗯 还真找到了一个base64.RawURLEncoding.DecodeString,赶紧试下

package main
 
import(
    "encoding/base64"
    "fmt"
)
 
func main(){
    encrypt := "Cf1WA2nBMo3H9G2UPhlLBBVBsMDl4udWr7__e6Iy93eIqLKi3EOjGhk8TkHujL1Uj6aGfZJNBzIbVE2NfNaz4pob8uiQvGaeTZdWP-8lFmAm6J1sz8N15xQkO7ADa5bNLCCqtlQbN2z7JcNenvFuID_rZGqb_1gmr-BGubGRMiMSK7RdjQYrMHaBcHLPB0UteakzcQwgKxCW7u0ECHqPJ39ne9JUG22JBWRo1ORuX5r30J_XrW3SQcdPSxfe0kvd61y12QOYh8VlOBBdBeDNnyDXefI_tDJDBFeqTXCgKu9wFkkWIZiM7WwqogaY-bvjUisbrPO4_fjJ1c0nWDOqRA"
    _,err := base64.RawURLEncoding.DecodeString(encrypt)
    if err != nil {
        fmt.Println(err)
    }
}

执行下,终于完美成功了。

总结

     base64编码过程有两部特殊操作

  •    url safe 将+/字符串转化成_-
  •    no padding is add  末尾不增加=号
base64.StdEncoding        // 标准的base64编码,如RFC 4648中所定义
base64.RawStdEncoding    // 与 StdEncoding 相同,但省略了填充字符
base64.URLEncoding        // RFC 4648中定义的备用base64编码。它通常用于URL和文件名。(将+/字符串转化成_-)
base64.RawURLEncoding    // 与 URLEncoding 相同,但省略了填充字符

 



转自:golang base64解码碰到的坑_base64.stdencoding.decodestring_只会打野怪我咯的博客-CSDN博客

posted @ 2023-09-03 14:43  ck_2016  Views(62)  Comments(0Edit  收藏  举报