1use crate::decoding::{compute_chunk, compute_decoded_size};
2use crate::errors::VerificationError;
3
4pub fn verify(encoded: &str) -> Result<(), VerificationError> {
11 let bytes = encoded.as_bytes();
12
13 let last_group_length = bytes.len() - bytes.len() / 11 * 11;
15 if let 1 | 4 | 8 = last_group_length {
16 return Err(VerificationError::InvalidLength);
17 }
18
19 let mut chunk_index = 0;
21 for chunk in bytes.chunks_exact(11) {
22 compute_chunk(chunk_index, chunk)?;
23 chunk_index += 11;
24 }
25
26 if last_group_length != 0 {
28 let chunk = &bytes[bytes.len() - last_group_length..];
29 let decoded = compute_chunk(chunk_index, chunk)?;
30 let elements_to_write = compute_decoded_size(last_group_length);
31
32 if decoded[elements_to_write..].iter().any(|v| *v != 0) {
33 return Err(VerificationError::NotCanonical);
34 }
35 }
36
37 Ok(())
38}
39
40#[cfg(test)]
45mod tests {
46 use super::*;
47 use crate::encode;
48
49 #[test]
50 fn test_verify_ok() {
51 for length in 0..16 {
52 for byte in 0..=255 {
53 let bytes = vec![byte; length];
54 let encoded = encode(&bytes);
55 verify(&encoded).expect("The verification must succeed");
56 }
57 }
58 }
59
60 #[test]
61 fn test_verify_invalid_length() {
62 let test = "JKLMNPQRSTUx";
63 let error = verify(test).expect_err("The verification must fail");
64
65 assert_eq!(
66 error,
67 VerificationError::InvalidLength,
68 "Incorrect for '{}'",
69 test
70 );
71
72 let test = "JKLMNPQRSTUxxxx";
75 let error = verify(test).expect_err("The verification must fail");
76
77 assert_eq!(
78 error,
79 VerificationError::InvalidLength,
80 "Incorrect for '{}'",
81 test
82 );
83
84 let test = "JKLMNPQRSTUxxxxxxxx";
87 let error = verify(test).expect_err("The verification must fail");
88
89 assert_eq!(
90 error,
91 VerificationError::InvalidLength,
92 "Incorrect for '{}'",
93 test
94 );
95 }
96
97 #[test]
98 fn test_verify_invalid_characters() {
99 let test = "Hello, world!";
100 let error = verify(test).expect_err("The verification must fail");
101
102 assert_eq!(
103 error,
104 VerificationError::InvalidByte {
105 index: 5,
106 byte: b',',
107 },
108 "Incorrect for '{}'",
109 test
110 );
111
112 let test = "THIS IS A TEST";
115 let error = verify(test).expect_err("The verification must fail");
116
117 assert_eq!(
118 error,
119 VerificationError::InvalidByte {
120 index: 2,
121 byte: b'I',
122 },
123 "Incorrect for '{}'",
124 test
125 );
126
127 let test = "TESTONTEST";
130 let error = verify(test).expect_err("The verification must fail");
131
132 assert_eq!(
133 error,
134 VerificationError::InvalidByte {
135 index: 4,
136 byte: b'O',
137 },
138 "Incorrect for '{}'",
139 test
140 );
141 }
142
143 #[test]
144 fn test_not_canonical() {
145 for i in ["0f", "2F", "5y", "BU", "Gv", "Nr", "Xd"] {
146 assert_eq!(
147 verify(i),
148 Err(VerificationError::NotCanonical),
149 "Incorrect for '{}'",
150 i
151 );
152 }
153 }
154}