common lisp 中非 ASCII 字符的无效 base64 编码

问题描述 投票:0回答:1

我正在将一些加密软件移植到 Common Lisp 中。这是我用多种其他语言做过的练习。它需要 UTF-8 字符串的 Base64 编码,包括非 ASCII 字符。我的第一个单元测试使用字符串“abcd£”检查这一点。 Base64 的预期值为“YWJjZMKj”。 (我也在 https://www.base64encode.org/ 上检查了这一点)。我尝试过两个 lisp 包,cl-base64 和 base64,每个都返回“YWJjZKM=”。

我在 Windows 10 上运行 sbcl 2.3.2。:SB-UNICODE 位于 FEATURES 列表中。我已经尝试过 cl-base64 提供的字符串和 usb8 数组。这是我的五点测试:

(in-package :rsearch-tests)

(def-suite test-encryption
    :description "test encryption functions")

(in-suite test-encryption)

(test feature
      (is-true (member :sb-unicode *features*) t))
(test base64-1
      (is (string= "YWJjZMKj" (cl-base64:string-to-base64-string "abcd£"))))
(test base64-3
      (is (string= "YWJjZMKj" (cl-base64:usb8-array-to-base64-string
                               (stdutils:string-to-usb8-array "abcd£")))))

这是测试字符串末尾的英镑符号。

这是测试输出:

Running test suite TEST-ENCRYPTION
 Running test FEATURE .
 Running test BASE64-1 f
 Running test BASE64-2 f
 Did 3 checks.
    Pass: 1 (33%)
    Skip: 0 ( 0%)
    Fail: 2 (66%)

 Failure Details:
 --------------------------------
 BASE64-2 in TEST-ENCRYPTION []:

(CL-BASE64:USB8-ARRAY-TO-BASE64-STRING (STDUTILS:STRING-TO-USB8-ARRAY "abcd£"))

 evaluated to

"YWJjZKM="

 which is not

STRING=

 to

"YWJjZMKj"


 --------------------------------
 --------------------------------
 BASE64-1 in TEST-ENCRYPTION []:

(CL-BASE64:STRING-TO-BASE64-STRING "abcd£")

 evaluated to

"YWJjZKM="

 which is not

STRING=

 to

"YWJjZMKj"


 --------------------------------
unicode base64 lisp common-lisp
1个回答
1
投票

几乎可以肯定,您没有正确处理 UTF-8,或者根本没有正确处理 UTF-8。特别是假设

stdutils
this 那么它的
string-to-usb8-array

(defun-exported string-to-usb8-array (str)
  (declare (simple-string str))
  (let* ((len (length str))
     (vec (make-usb8-array len)))
    (declare (fixnum len)
         (type (simple-array (unsigned-byte 8) (*)) vec)
         (optimize (speed 3)))
    (do ((i 0 (1+ i)))
    ((= i len) vec)
      (declare (fixnum i))
      (setf (aref vec i) (char-code (schar str i))))))

它甚至没有尝试处理 UTF-8。巧合的是,它“有效”,因为

#\£
的字符代码小于 256。

我没有检查过其他案例,但我确定是一样的。

如果您需要对字符串的 UTF-8 表示形式进行 Base64 编码,您需要确保将其转换为 UTF-8 编码,或者 Base64 编码器会为您完成此操作。特别是,CL 中不存在“UTF-8 字符串”这样的东西:CL 字符串是字符向量,而不是八位位组向量,八位位组是这些字符的某种编码。 (如果您已经知道这一点,我们深表歉意。)

© www.soinside.com 2019 - 2024. All rights reserved.