blob: 504acbfa4f73a85443320efb826293bfb94f5718 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
;;; guile-email --- Guile email parser
;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
;;;
;;; This file is part of guile-email.
;;;
;;; guile-email is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU Affero General Public License as
;;; published by the Free Software Foundation; either version 3 of the
;;; License, or (at your option) any later version.
;;;
;;; guile-email is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;; Affero General Public License for more details.
;;;
;;; You should have received a copy of the GNU Affero General Public
;;; License along with guile-email. If not, see
;;; <http://www.gnu.org/licenses/>.
(use-modules (email base64)
(ice-9 iconv))
(load "encoding.scm")
(define (string-has-only-valid-base64-characters? str)
(string-every (char-set-union
(char-set #\newline #\return #\space)
(ucs-range->char-set (char->integer #\A) (1+ (char->integer #\Z)))
(ucs-range->char-set (char->integer #\a) (1+ (char->integer #\z)))
(ucs-range->char-set (char->integer #\0) (1+ (char->integer #\9)))
(char-set #\+ #\/ #\=))
str))
(test-begin "base64")
(let ((decoded-text
"Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.")
(encoded-text
"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=")
(charset "UTF-8"))
(test-equal "base64 wikipedia example: decoding"
(bytevector->string (base64-decode encoded-text) charset)
decoded-text)
(test-equal "base64 wikipedia example: encoding"
(base64-encode
(string->bytevector decoded-text charset))
encoded-text)
(test-assert "base64 wikipedia example: encoded output should not be more than 76 columns wide"
(each-line-has-a-maximum-of-76-characters?
(base64-encode
(string->bytevector decoded-text charset)))))
(test-assert "base64 random bytevector: base64-encode and base64-decode are inverses of each other"
(every (lambda (len)
(let ((x (random-bytevector len)))
(equal? x (base64-decode (base64-encode x)))))
(iota 1000)))
(test-assert "base64 random bytevector: encoded output should not be more than 76 columns wide"
(every (lambda (len)
(each-line-has-a-maximum-of-76-characters?
(base64-encode (random-bytevector len))))
(iota 1000)))
(test-assert "base64 random bytevector: encoded output must only consist of characters from the base64 alphabet"
(every (lambda (len)
(string-has-only-valid-base64-characters?
(base64-encode (random-bytevector len))))
(iota 1000)))
(test-equal "base64 decoding should ignore invalid characters"
(bytevector->string (base64-decode "..TWFu,") "utf-8")
"Man")
(test-end "base64")
|