对于看似有效的 png,输入字节中的非法 base64 数据
Illegal base64 data at input byte for seemingly valid png
我正在尝试解码从 javascript canvas' toDataURL 函数生成的数据 URL。
以下 golang 应用程序失败并出现错误 illegal base64 data at input byte 129)
package main
import (
"encoding/base64"
"fmt"
"net/url"
"strings"
)
func main() {
pngData := "iVBORw0KGgoAAAANSUhEUgAAAF0AAAABCAYAAAC8PaJPAAAABHNCSVQICAgIfAhkiAAAALVJREFUGFdt0MsKQVEYhuG9CeU0VgamihBl6hqMXYoLchduQFuKicyFARPn0/J+9Q2tevrba639H1YcQhhHUTTBACloFZHFw3FJbODj7xdxjSqmqGCHms+3vv8m3nDwWSA+vVcipjFHHlcMcUTBtcuueSHqfgzlVJ7Nn/o99s5Qf3v0sUAHK///JbahmZQ3gy4S96OZc9A90fkdepM6tNTHDOqz6T3NofeTluuqV82oHOrphNEPw3UwfBVmbU4AAAAASUVORK5CYII="
pngData, err := url.PathUnescape(pngData)
if err != nil {
fmt.Printf("Failed to unescape", err.Error())
return
}
pngData = strings.Replace(pngData, "+", "", -1)
_, err = base64.URLEncoding.WithPadding(base64.NoPadding).DecodeString(pngData)
if err != nil {
fmt.Printf("Failed to decode", err.Error())
}
}
如果我将 pngData 中的值传递给 web-based base64 to png converter,则生成图像没有问题。 (白色值的水平线)
我已经尝试过 StdEncoding、RawURLEncoding 和它们的 Raw 对应物。我也尝试过使用或不使用填充,并且我尝试了相同的 pngData 字符串,但带有附加的 = 而没有尾随 =.
关于 Golang 为何拒绝解码此数据的任何想法?
我从 canvas 解码得到的一些图像很好。但是有些,比如这个,没有。
这似乎工作正常:
package main
import (
"encoding/base64"
"image"
"image/png"
"os"
"strings"
)
func main() {
s := `iVBORw0KGgoAAAANSUhEUgAAAF0AAAABCAYAAAC8PaJPAAAABHNCSVQICAgIfAhkiAAAALVJ
REFUGFdt0MsKQVEYhuG9CeU0VgamihBl6hqMXYoLchduQFuKicyFARPn0/J+9Q2tevrba639H1YcQhhHU
TTBACloFZHFw3FJbODj7xdxjSqmqGCHms+3vv8m3nDwWSA+vVcipjFHHlcMcUTBtcuueSHqfgzlVJ7Nn/
o99s5Qf3v0sUAHK///JbahmZQ3gy4S96OZc9A90fkdepM6tNTHDOqz6T3NofeTluuqV82oHOrphNEPw3U
wfBVmbU4AAAAASUVORK5CYII=`
d := base64.NewDecoder(base64.StdEncoding, strings.NewReader(s))
p, e := png.Decode(d)
if e != nil {
panic(e)
}
c, e := os.Create("a.png")
if e != nil {
panic(e)
}
png.Encode(c, p.(*image.NRGBA))
}
显示了一种方法,但我不得不问:
为什么叫url.PathUnescape
?数据不包含路径转义字符(无 %
编码)。这个电话是无害的,但没有必要。
为什么使用替代编码 (URLEncoding
)?正如我们在 base64 package documentation 中看到的,标准编码和备用编码之间的区别在于备用编码使用 -
和 _
代替 +
和 /
.但是我们看数据串,里面有加号和斜杠,没有破折号和下划线,显然是用标准编码编码的。
为什么叫base64.NoPadding
?输入数据以=
结尾,这是一个填充字符。
你为什么要通过base64.URLEncoding.WithPadding(base64.NoPadding)
base64.NoPadding
?文档告诉我们,这可以拼写为 base64.RawURLEncoding
.
为什么您明确要求删除 +
个字符(不是一个好主意)而不是 /
个字符?
如果我们放弃所有这些(并为了发布目的拆分一长行输入),我们会得到这个 (playground link):
package main
import (
"encoding/base64"
"fmt"
)
func main() {
data := "iVBORw0KGgoAAAANSUhEUgAAAF0AAAABCAYAAAC8PaJPAAAABH" +
"NCSVQICAgIfAhkiAAAALVJREFUGFdt0MsKQVEYhuG9CeU0Vgam" +
"ihBl6hqMXYoLchduQFuKicyFARPn0/J+9Q2tevrba639H1YcQh" +
"hHUTTBACloFZHFw3FJbODj7xdxjSqmqGCHms+3vv8m3nDwWSA+" +
"vVcipjFHHlcMcUTBtcuueSHqfgzlVJ7Nn/o99s5Qf3v0sUAHK/" +
"//JbahmZQ3gy4S96OZc9A90fkdepM6tNTHDOqz6T3NofeTluuq" +
"V82oHOrphNEPw3UwfBVmbU4AAAAASUVORK5CYII="
b, err := base64.StdEncoding.DecodeString(data)
if err != nil {
fmt.Printf("Failed to decode: %s\n", err)
} else {
fmt.Printf("bytes begin with: %q\n", b[0:4])
}
}
我正在尝试解码从 javascript canvas' toDataURL 函数生成的数据 URL。
以下 golang 应用程序失败并出现错误 illegal base64 data at input byte 129)
package main
import (
"encoding/base64"
"fmt"
"net/url"
"strings"
)
func main() {
pngData := "iVBORw0KGgoAAAANSUhEUgAAAF0AAAABCAYAAAC8PaJPAAAABHNCSVQICAgIfAhkiAAAALVJREFUGFdt0MsKQVEYhuG9CeU0VgamihBl6hqMXYoLchduQFuKicyFARPn0/J+9Q2tevrba639H1YcQhhHUTTBACloFZHFw3FJbODj7xdxjSqmqGCHms+3vv8m3nDwWSA+vVcipjFHHlcMcUTBtcuueSHqfgzlVJ7Nn/o99s5Qf3v0sUAHK///JbahmZQ3gy4S96OZc9A90fkdepM6tNTHDOqz6T3NofeTluuqV82oHOrphNEPw3UwfBVmbU4AAAAASUVORK5CYII="
pngData, err := url.PathUnescape(pngData)
if err != nil {
fmt.Printf("Failed to unescape", err.Error())
return
}
pngData = strings.Replace(pngData, "+", "", -1)
_, err = base64.URLEncoding.WithPadding(base64.NoPadding).DecodeString(pngData)
if err != nil {
fmt.Printf("Failed to decode", err.Error())
}
}
如果我将 pngData 中的值传递给 web-based base64 to png converter,则生成图像没有问题。 (白色值的水平线)
我已经尝试过 StdEncoding、RawURLEncoding 和它们的 Raw 对应物。我也尝试过使用或不使用填充,并且我尝试了相同的 pngData 字符串,但带有附加的 = 而没有尾随 =.
关于 Golang 为何拒绝解码此数据的任何想法?
我从 canvas 解码得到的一些图像很好。但是有些,比如这个,没有。
这似乎工作正常:
package main
import (
"encoding/base64"
"image"
"image/png"
"os"
"strings"
)
func main() {
s := `iVBORw0KGgoAAAANSUhEUgAAAF0AAAABCAYAAAC8PaJPAAAABHNCSVQICAgIfAhkiAAAALVJ
REFUGFdt0MsKQVEYhuG9CeU0VgamihBl6hqMXYoLchduQFuKicyFARPn0/J+9Q2tevrba639H1YcQhhHU
TTBACloFZHFw3FJbODj7xdxjSqmqGCHms+3vv8m3nDwWSA+vVcipjFHHlcMcUTBtcuueSHqfgzlVJ7Nn/
o99s5Qf3v0sUAHK///JbahmZQ3gy4S96OZc9A90fkdepM6tNTHDOqz6T3NofeTluuqV82oHOrphNEPw3U
wfBVmbU4AAAAASUVORK5CYII=`
d := base64.NewDecoder(base64.StdEncoding, strings.NewReader(s))
p, e := png.Decode(d)
if e != nil {
panic(e)
}
c, e := os.Create("a.png")
if e != nil {
panic(e)
}
png.Encode(c, p.(*image.NRGBA))
}
为什么叫
url.PathUnescape
?数据不包含路径转义字符(无%
编码)。这个电话是无害的,但没有必要。为什么使用替代编码 (
URLEncoding
)?正如我们在 base64 package documentation 中看到的,标准编码和备用编码之间的区别在于备用编码使用-
和_
代替+
和/
.但是我们看数据串,里面有加号和斜杠,没有破折号和下划线,显然是用标准编码编码的。为什么叫
base64.NoPadding
?输入数据以=
结尾,这是一个填充字符。你为什么要通过
base64.URLEncoding.WithPadding(base64.NoPadding)
base64.NoPadding
?文档告诉我们,这可以拼写为base64.RawURLEncoding
.为什么您明确要求删除
+
个字符(不是一个好主意)而不是/
个字符?
如果我们放弃所有这些(并为了发布目的拆分一长行输入),我们会得到这个 (playground link):
package main
import (
"encoding/base64"
"fmt"
)
func main() {
data := "iVBORw0KGgoAAAANSUhEUgAAAF0AAAABCAYAAAC8PaJPAAAABH" +
"NCSVQICAgIfAhkiAAAALVJREFUGFdt0MsKQVEYhuG9CeU0Vgam" +
"ihBl6hqMXYoLchduQFuKicyFARPn0/J+9Q2tevrba639H1YcQh" +
"hHUTTBACloFZHFw3FJbODj7xdxjSqmqGCHms+3vv8m3nDwWSA+" +
"vVcipjFHHlcMcUTBtcuueSHqfgzlVJ7Nn/o99s5Qf3v0sUAHK/" +
"//JbahmZQ3gy4S96OZc9A90fkdepM6tNTHDOqz6T3NofeTluuq" +
"V82oHOrphNEPw3UwfBVmbU4AAAAASUVORK5CYII="
b, err := base64.StdEncoding.DecodeString(data)
if err != nil {
fmt.Printf("Failed to decode: %s\n", err)
} else {
fmt.Printf("bytes begin with: %q\n", b[0:4])
}
}