c# equivalent of base64 + UrlTokenEncode in clojure
本文关键字:UrlTokenEncode in clojure base64 equivalent of | 更新日期: 2023-09-27 18:32:52
我在 C# 中有一段代码,它对字符串进行编码并返回 URL 安全字符串(稍后会解码)
string stringToEncrypt = "Winter is coming";
byte[] bytes = new byte[stringToEncrypt.Length * sizeof(char)];
System.Buffer.BlockCopy(stringToEncrypt.ToCharArray(), 0, bytes, 0, bytes.Length);
System.Web.HttpServerUtility.UrlTokenEncode(bytes).Dump();
Dump
来自LinqPad。我用它来快速测试 C# 的零碎部分
这将在执行时返回VwBpAG4AdABlAHIAIABpAHMAIABjAG8AbQBpAG4AZwA1
。
我现在正在尝试从 clojure 服务中做同样的事情。使用encode
库并按照这个答案当我有
(String. (b64/encode (.getBytes email)) "UTF-8")
我得到V2ludGVyIGlzIGNvbWluZw==
,这是
- 未进行网址编码
- 与 C# 版本不匹配。
尝试查看 MSDN 文档以获取UrlTokenEncode()
,但它没有太多关于它实现的细节,以了解幕后发生了什么。
我可以在 clojure 中生成等效的字符串吗?
感谢罗伯特指出UrlTokenEncode
的来源。 它执行以下操作:
- 对输入字节进行 Base64 编码
- 将任何尾随填充
=
替换为填充字符数(1
或2
) - 将
+
替换为-
,将/
替换为_
另一个基本细节是 C# 示例对字符串的 UTF-16 表示形式进行编码(每个字符 2 个字节)。 为了说明这一点,这里有一个来自围棋游乐场的例子:http://play.golang.org/p/UlKMa7_OwV
此代码为测试输入生成预期输出:
(ns blah.core
(:require [clojure.data.codec.base64 :as b64])
(:require [clojure.string :as string])
(:gen-class))
(defn encode [original]
(let [bytes_in (.getBytes original "UTF-16LE")
bytes_enc (b64/encode bytes_in)
bytes_len (alength bytes_enc)
pad_count (b64/pad-length bytes_enc 0 bytes_len)
enc_string (String. bytes_enc 0 (- bytes_len pad_count) "UTF-8")
enc_string (string/replace enc_string '+ '-)
enc_string (string/replace enc_string '/ '_)]
(str enc_string pad_count)))
(defn -main
[& args]
(let [message "Winter is coming"]
(println message)
(println (encode message))))
解码功能留给读者作为练习。
如果您使用的是 Java 8,则新的 Base64
类以及用于填充计数的一点模块化算法可以做到这一点:
(defn url-token-encode [bytes]
(let [byte-count (count bytes)]
(if (pos? byte-count)
(str (.. (java.util.Base64/getUrlEncoder) (withoutPadding) (encodeToString bytes))
(mod (- byte-count) 3))
"")))
(defn encode [s]
(url-token-encode (.getBytes s "UTF-16LE")))
(encode "Winter is coming")
;=>"VwBpAG4AdABlAHIAIABpAHMAIABjAG8AbQBpAG4AZwA1"