我有一段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==,这是
不是url编码的
与C版不匹配。
尝试查看UrlTokenEncode()的msdn文档,但是没有太多关于它实现的细节,无法查看引擎盖下发生了什么。
我可以在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))))

解码功能留给读者作为练习。

08-07 07:20