为了账号安全,请及时绑定邮箱和手机立即绑定

golang如何将65537转为AQAB

golang如何将65537转为AQAB

Go
MYYA 2022-06-27 15:03:16
我正在围绕 JWT 创建和验证编写一些单元和集成测试。我正在使用我用 openssl 创建的真实(良好自签名)证书拼凑一个快速 JWKS 页面,我一直在做饭,直到遇到这个非常简单的问题:“E”值是 65537,但在 JWKS 中它应该是 AQAB。在墙上敲了很长时间后,我终于在纸上弄清楚了。https://www.rfc-editor.org/rfc/rfc7518#section-6.3.1.265537 是 0000 0001: 0000 0000 : 0000 0001如果您将其转换为 base64 的 6 位,您将得到000000 010000 000000 000001哪个是 AQABhttps://en.wikipedia.org/wiki/Base64#Base64_table所以我尝试编写一些快速代码。但事实证明它并不快。我在想,一定有更简单的方法。我尝试的所有 base64 编码都给了我超过 3 个字节的空间。任何有自尊的程序员都会做的事情也是如此……我看到每个人都使用 65537,所以我对那个傻瓜进行了硬编码并继续前进,但它一直在唠叨我。我讨厌困扰我的问题。我得到的最接近的是:bs := make([]byte, 4)binary.BigEndian.PutUint32(bs, 65537)fmt.Println(bs)fmt.Println(base64.URLEncoding.EncodeToString(bs))其中产生:[0 1 0 1]AAEAAQ==我的快速数学说,base64 输出是为什么超过 3 个字节:D
查看完整描述

1 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

你是base64编码4个二进制字节:


bs := make([]byte, 4) // `AAEAAQ==`

这将产生 6 ( 4*8/6) 个 base64 字符 - 加上==填充。


您想对三个二进制字节进行编码 - 这将产生 4 ( 3*8/6) 个 base64 字符。


bs := []byte{1, 0, 1}

fmt.Println(bs)

fmt.Println(base64.URLEncoding.EncodeToString(bs)) // `AQAB`

https://play.golang.org/p/gDviu06pftR


编辑


因此,您只需要较低的 3 个字节(如果使用 BigEndian,则在末尾)。


所以你可以使用你的原始代码:


bs := make([]byte, 4)

binary.BigEndian.PutUint32(bs, 65537)


bs = bs[1:] // drop most significant byte - leaving least-significant 3-bytes


fmt.Println(base64.URLEncoding.EncodeToString(bs)) // `AQAB`

或者,如果您查看binary.BigEndian.PutUint32的来源,您可以看到它如何从uint32- 中提取 4 个字节,并对 3 个字节执行相同操作:


bs := make([]byte, 3)


v := 65537

bs[0] = byte(v >> 16)

bs[1] = byte(v >> 8)

bs[2] = byte(v)


fmt.Println(base64.URLEncoding.EncodeToString(bs)) // `AQAB`

https://play.golang.org/p/xTNzZMeQWVx


查看完整回答
反对 回复 2022-06-27
  • 1 回答
  • 0 关注
  • 176 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信