1
2## tests for digest, taken from the examples in the manual page
3
4suppressMessages(library(digest))
5
6## Standard RFC 1321 test vectors
7md5Input <-
8    c("",
9      "a",
10      "abc",
11      "message digest",
12      "abcdefghijklmnopqrstuvwxyz",
13      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
14      paste("12345678901234567890123456789012345678901234567890123456789012",
15            "345678901234567890", sep=""))
16md5Output <-
17    c("d41d8cd98f00b204e9800998ecf8427e",
18      "0cc175b9c0f1b6a831c399e269772661",
19      "900150983cd24fb0d6963f7d28e17f72",
20      "f96b697d7cb7938d525a2f31aaf161d0",
21      "c3fcd3d76192e4007dfb496cca67e13b",
22      "d174ab98d277d9f5a5611c2c9f419d9f",
23      "57edf4a22be3c955ac49da2e2107b67a")
24
25for (i in seq(along.with=md5Input)) {
26    md5 <- digest(md5Input[i], serialize=FALSE)
27    expect_true(identical(md5, md5Output[i]))
28    #cat(md5, "\n")
29}
30
31md5 <- getVDigest()
32expect_identical(md5(md5Input, serialize = FALSE), md5Output)
33
34expect_identical(digest(NULL),
35                 md5(NULL))
36expect_identical(digest(character(0)),
37                 md5(character(0)))
38expect_identical(digest(list("abc")),
39                 md5(list(list("abc"))))
40expect_identical(digest(list(NULL)),
41                 md5(list(list(NULL))))
42expect_identical(digest(character(0), serialize = FALSE),
43                 md5(character(0), serialize = FALSE))
44
45
46## md5 raw output test
47for (i in seq(along.with=md5Input)) {
48    md5 <- digest(md5Input[i], serialize=FALSE, raw=TRUE)
49    md5 <- gsub(" ","",capture.output(cat(md5)))
50    expect_true(identical(md5, md5Output[i]))
51    #cat(md5, "\n")
52}
53
54sha1Input <-
55    c("abc",
56      "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
57      NULL)
58sha1Output <-
59    c("a9993e364706816aba3e25717850c26c9cd0d89d",
60      "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
61      "34aa973cd4c4daa4f61eeb2bdbad27316534016f")
62
63for (i in seq(along.with=sha1Input)) {
64    sha1 <- digest(sha1Input[i], algo="sha1", serialize=FALSE)
65    expect_true(identical(sha1, sha1Output[i]))
66    #cat(sha1, "\n")
67}
68
69sha1 <- getVDigest(algo = 'sha1')
70expect_identical(sha1(sha1Input, serialize = FALSE), sha1Output[1:2])
71
72## sha1 raw output test
73for (i in seq(along.with=sha1Input)) {
74    sha1 <- digest(sha1Input[i], algo="sha1", serialize=FALSE, raw=TRUE)
75    #print(sha1)
76    sha1 <- gsub(" ","",capture.output(cat(sha1)))
77    #print(sha1)
78    #print(sha1Output[i])
79    expect_true(identical(sha1, sha1Output[i]))
80    #cat(sha1, "\n")
81}
82
83## sha512 test
84sha512Input <-c(
85    "",
86    "The quick brown fox jumps over the lazy dog."
87    )
88sha512Output <- c(
89    "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
90    "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed")
91
92for (i in seq(along.with=sha512Input)) {
93    sha512 <- digest(sha512Input[i], algo="sha512", serialize=FALSE)
94    expect_true(identical(sha512, sha512Output[i]))
95    #cat(sha512, "\n")
96}
97
98sha512 <- getVDigest(algo = 'sha512')
99expect_identical(sha512(sha512Input, serialize = FALSE), sha512Output[1:2])
100
101## sha512 raw output test
102for (i in seq(along.with=sha512Input)) {
103    sha512 <- digest(sha512Input[i], algo="sha512", serialize=FALSE, raw=TRUE)
104    #print(sha512)
105
106    sha512 <- gsub(" ","",capture.output(cat(sha512)))
107    #print(sha512)
108    #print(sha512Output[i])
109    expect_true(identical(sha512, sha512Output[i]))
110    #cat(sha512, "\n")
111}
112
113crc32Input <-
114    c("abc",
115      "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
116      NULL)
117crc32Output <-
118    c("352441c2",
119      "171a3f5f",
120      "2ef80172")
121
122for (i in seq(along.with=crc32Input)) {
123    crc32 <- digest(crc32Input[i], algo="crc32", serialize=FALSE)
124    expect_true(identical(crc32, crc32Output[i]))
125    #cat(crc32, "\n")
126}
127
128crc32 <- getVDigest(algo = 'crc32')
129expect_identical(crc32(crc32Input, serialize = FALSE), crc32Output[1:2])
130
131
132## one of the FIPS-
133sha1 <- digest("abc", algo="sha1", serialize=FALSE)
134expect_true(identical(sha1, "a9993e364706816aba3e25717850c26c9cd0d89d"))
135
136## This one seems to give slightly different output depending on the R version used
137##
138##                                      # example of a digest of a standard R list structure
139## cat(digest(list(LETTERS, data.frame(a=letters[1:5],
140##                                     b=matrix(1:10,
141##                                     ncol=2)))), "\n")
142
143## these outputs were calculated using xxh32sum
144xxhash32Input <-
145    c("abc",
146      "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
147      "")
148xxhash32Output <-
149    c("32d153ff",
150      "89ea60c3",
151      "02cc5d05")
152
153for (i in seq(along.with=xxhash32Input)) {
154    xxhash32 <- digest(xxhash32Input[i], algo="xxhash32", serialize=FALSE)
155    #cat(xxhash32, "\n")
156    expect_true(identical(xxhash32, xxhash32Output[i]))
157}
158
159xxhash32 <- getVDigest(algo = 'xxhash32')
160expect_identical(xxhash32(xxhash32Input, serialize = FALSE), xxhash32Output)
161
162
163## these outputs were calculated using xxh64sum
164xxhash64Input <-
165    c("abc",
166      "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
167      "")
168xxhash64Output <-
169    c("44bc2cf5ad770999",
170      "f06103773e8585df",
171      "ef46db3751d8e999")
172
173for (i in seq(along.with=xxhash64Input)) {
174    xxhash64 <- digest(xxhash64Input[i], algo="xxhash64", serialize=FALSE)
175    #cat(xxhash64, "\n")
176    expect_true(identical(xxhash64, xxhash64Output[i]))
177}
178
179xxhash64 <- getVDigest(algo = 'xxhash64')
180expect_identical(xxhash64(xxhash64Input, serialize = FALSE), xxhash64Output)
181
182
183## these outputs were calculated using mmh3 python package
184## the first two are also shown at this StackOverflow question on test vectors
185##   https://stackoverflow.com/questions/14747343/murmurhash3-test-vectors
186murmur32Input <-
187    c("abc",
188      "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
189      "")
190murmur32Output <-
191    c("b3dd93fa",
192      "ee925b90",
193      "00000000")
194
195for (i in seq(along.with=murmur32Input)) {
196    murmur32 <- digest(murmur32Input[i], algo="murmur32", serialize=FALSE)
197    #cat(murmur32, "\n")
198    expect_true(identical(murmur32, murmur32Output[i]))
199}
200
201murmur32 <- getVDigest(algo = 'murmur32')
202expect_identical(murmur32(murmur32Input, serialize = FALSE), murmur32Output)
203
204
205## tests for digest spooky
206
207expect_true(require(digest))
208
209## test vectors (originally for md5)
210spookyInput <-
211  c("",
212    "a",
213    "abc",
214    "message digest",
215    "abcdefghijklmnopqrstuvwxyz",
216    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
217    paste("12345678901234567890123456789012345678901234567890123456789012",
218          "345678901234567890", sep=""))
219
220# from spooky import hash128
221# from binascii import hexlify
222#
223# spookyInput = [
224#     "",
225#       "a",
226#       "abc",
227#       "message digest",
228#       "abcdefghijklmnopqrstuvwxyz",
229#       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
230#       "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
231#     ]
232#
233# for s in spookyInput:
234#     hexlify(hash128(s).to_bytes(16, 'little')).decode()
235#
236# '1909f56bfc062723c751e8b465ee728b'
237# 'bdc9bba09181101a922a4161f0584275'
238# '67c93775f715ab8ab01178caf86713c6'
239# '9630c2a55c0987a0db44434f9d67a192'
240# '5172de938ce149a98f4d06d3c3168ffe'
241# 'b5b3b2d0f08b58aa07f551895f929f81'
242# '3621ec01112dafa1610a4bd23041966b'
243
244spookyOutputPython <-
245  c(
246    '1909f56bfc062723c751e8b465ee728b',
247    'bdc9bba09181101a922a4161f0584275',
248    '67c93775f715ab8ab01178caf86713c6',
249    '9630c2a55c0987a0db44434f9d67a192',
250    '5172de938ce149a98f4d06d3c3168ffe',
251    'b5b3b2d0f08b58aa07f551895f929f81',
252    '3621ec01112dafa1610a4bd23041966b'
253  )
254
255## spooky raw output test
256for (i in seq(along.with=spookyInput)) {
257  # skip = 30 skips the entire serialization header for a length 1 character vector
258  # this is equivalent to raw = TRUE and matches the python spooky implementation for those vectors
259  spooky <- digest(spookyInput[i], algo = "spookyhash", skip = 30)
260  expect_true(identical(spooky, spookyOutputPython[i]))
261  #cat(spooky, "\n")
262}
263
264expect_identical(
265  getVDigest(algo = 'spookyhash')(spookyInput, skip = 30),
266  spookyOutputPython
267)
268
269## some extras to get coverage up - these aren't tested against reference output,
270## just output from R 3.6.0
271spookyInput <- c("a", "aaaaaaaaa", "aaaaaaaaaaaaa")
272spookyOutput <- c(
273  "b7a3573ba6139dfdc52db30acba87f46",
274  "fd876ecaa5d1e442600333118f223e02",
275  "91848873bf91d06ad321bbd47400a556"
276)
277for (i in seq(along.with=spookyInput)) {
278  spooky <- digest(spookyInput[i], algo = "spookyhash")
279  expect_true(identical(spooky, spookyOutput[i]))
280  #cat(spooky, "\n")
281}
282
283expect_identical(
284  getVDigest(algo = 'spookyhash')(spookyInput),
285  spookyOutput
286)
287
288# test a bigger object
289spooky <- digest(iris, algo = "spookyhash")
290expect_true(identical(spooky, "af58add8b4f7044582b331083bc239ff"))
291expect_identical(getVDigest('spookyhash')(list(iris)),
292                 "af58add8b4f7044582b331083bc239ff")
293#cat(spooky, "\n")
294
295# test error message
296#error.message <- try(digest(spookyInput[i], algo = "spookyhash", serialize = FALSE))
297#expect_true(
298#  grepl("spookyhash algorithm is not available without serialization.", error.message)
299#)
300
301
302## Ensure that all values of algo are actually allowed (in case a new one is
303## added in the future). The call to match.arg() passes choices explicitly
304## because it is significantly faster to do it than to have it automatically
305## infer the possible choices from the function's formals.
306
307# Grab the possible values of algo, then call digest() for each one.
308algos <- eval(formals(digest)$algo)
309for (algo in algos) {
310  digest(123, algo = algo)
311}
312# Same for getVDigest
313algos <- eval(formals(getVDigest)$algo)
314for (algo in algos) {
315  getVDigest(algo = algo)
316}
317