GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
hash.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2007-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 /*
27 Implementation note (Dec, 2015): All supported cryptographic hash
28 functions are calling "low-level" implementations of the GNULIB.
29 
30 The GNULIB, contains even more HMAC based algorithms, c.f.
31 https://www.gnu.org/software/gnulib/MODULES.html#module=crypto/hmac-md5
32 so a future project might be including these algorithms as well, adding
33 a third key input parameter. There is also a GNULIB "high-level"
34 interface to Libcrypt. It might be easier to use, but it introduces
35 a new build dependency, so better stick to the "low-level" functions
36 for now.
37 */
38 
39 #if defined (HAVE_CONFIG_H)
40 # include "config.h"
41 #endif
42 
43 #include <string>
44 
45 #include "lo-hash.h"
46 
47 #include "defun.h"
48 #include "error.h"
49 #include "ov.h"
50 #include "ovl.h"
51 
53 
54 DEFUN (hash, args, ,
55  doc: /* -*- texinfo -*-
56 @deftypefn {} {@var{hashval} =} hash ("@var{hashfcn}", @var{str})
57 Calculate the hash value of the string @var{str} using the hash function
58 @var{hashfcn}.
59 
60 The available hash functions are given in the table below.
61 
62 @table @samp
63 @item MD2
64 Message-Digest Algorithm 2 (RFC 1319).
65 
66 @item MD4
67 Message-Digest Algorithm 4 (RFC 1320).
68 
69 @item MD5
70 Message-Digest Algorithm 5 (RFC 1321).
71 
72 @item SHA1
73 Secure Hash Algorithm 1 (RFC 3174)
74 
75 @item SHA224
76 Secure Hash Algorithm 2 (224 Bits, RFC 3874)
77 
78 @item SHA256
79 Secure Hash Algorithm 2 (256 Bits, RFC 6234)
80 
81 @item SHA384
82 Secure Hash Algorithm 2 (384 Bits, RFC 6234)
83 
84 @item SHA512
85 Secure Hash Algorithm 2 (512 Bits, RFC 6234)
86 @end table
87 
88 To calculate for example the MD5 hash value of the string
89 @nospell{@qcode{"abc"}} the @code{hash} function is called as follows:
90 
91 @example
92 @group
93 hash ("md5", "abc")
94  @print{} ans = 900150983cd24fb0d6963f7d28e17f72
95 @end group
96 @end example
97 
98 For the same string, the SHA-1 hash value is calculated with:
99 
100 @example
101 @group
102 hash ("sha1", "abc")
103  @print{} ans = a9993e364706816aba3e25717850c26c9cd0d89d
104 @end group
105 @end example
106 
107 And to compute the hash value of a file, e.g., @code{file = "file.txt"},
108 call @code{hash} in combination with the @code{fileread}:
109 
110 @example
111 @group
112 hash ("md5", fileread (file));
113 @end group
114 @end example
115 
116 @end deftypefn */)
117 {
118  if (args.length () != 2)
119  print_usage ();
120 
121  std::string hash_type = args(0).string_value ();
122  std::string str = args(1).string_value ();
123 
124  return ovl (crypto::hash (hash_type, str));
125 }
126 
127 /*
128 ## MD2 test suite (RFC 1319)
129 %!assert (hash ("md2", ""), "8350e5a3e24c153df2275c9f80692773")
130 %!assert (hash ("md2", "a"), "32ec01ec4a6dac72c0ab96fb34c0b5d1")
131 %!assert (hash ("md2", "abc"), "da853b0d3f88d99b30283a69e6ded6bb")
132 %!assert (hash ("md2", "message digest"), "ab4f496bfb2a530b219ff33031fe06b0")
133 %!assert (hash ("md2", "abcdefghijklmnopqrstuvwxyz"),
134 %! "4e8ddff3650292ab5a4108c3aa47940b");
135 %!assert (hash ("md2", ["ABCDEFGHIJKLMNOPQRSTUVWXYZ", ...
136 %! "abcdefghijklmnopqrstuvwxyz0123456789"]),
137 %! "da33def2a42df13975352846c30338cd");
138 %!assert (hash ("md2", ["123456789012345678901234567890123456789", ...
139 %! "01234567890123456789012345678901234567890"]),
140 %! "d5976f79d83d3a0dc9806c3c66f3efd8");
141 
142 ## MD4 test suite (RFC 1320)
143 %!assert (hash ("md4", ""), "31d6cfe0d16ae931b73c59d7e0c089c0")
144 %!assert (hash ("md4", "a"), "bde52cb31de33e46245e05fbdbd6fb24")
145 %!assert (hash ("md4", "abc"), "a448017aaf21d8525fc10ae87aa6729d")
146 %!assert (hash ("md4", "message digest"), "d9130a8164549fe818874806e1c7014b")
147 %!assert (hash ("md4", "abcdefghijklmnopqrstuvwxyz"),
148 %! "d79e1c308aa5bbcdeea8ed63df412da9");
149 %!assert (hash ("md4", ["ABCDEFGHIJKLMNOPQRSTUVWXYZ", ...
150 %! "abcdefghijklmnopqrstuvwxyz0123456789"]),
151 %! "043f8582f241db351ce627e153e7f0e4");
152 %!assert (hash ("md4", ["123456789012345678901234567890123456789", ...
153 %! "01234567890123456789012345678901234567890"]),
154 %! "e33b4ddc9c38f2199c3e7b164fcc0536");
155 
156 ## MD5 test suite (RFC 1321)
157 %!assert (hash ("md5", ""), "d41d8cd98f00b204e9800998ecf8427e")
158 %!assert (hash ("md5", "a"), "0cc175b9c0f1b6a831c399e269772661")
159 %!assert (hash ("md5", "abc"), "900150983cd24fb0d6963f7d28e17f72")
160 %!assert (hash ("md5", "message digest"), "f96b697d7cb7938d525a2f31aaf161d0")
161 %!assert (hash ("md5", "abcdefghijklmnopqrstuvwxyz"),
162 %! "c3fcd3d76192e4007dfb496cca67e13b");
163 %!assert (hash ("md5", ["ABCDEFGHIJKLMNOPQRSTUVWXYZ", ...
164 %! "abcdefghijklmnopqrstuvwxyz0123456789"]),
165 %! "d174ab98d277d9f5a5611c2c9f419d9f");
166 %!assert (hash ("md5", ["123456789012345678901234567890123456789", ...
167 %! "01234567890123456789012345678901234567890"]),
168 %! "57edf4a22be3c955ac49da2e2107b67a");
169 
170 ## SHA1 test suite (RFC 3174) and more
171 %!assert (hash ("sha1", ""), "da39a3ee5e6b4b0d3255bfef95601890afd80709")
172 %!assert (hash ("sha1", "a"), "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8")
173 %!assert (hash ("sha1", "abc"), "a9993e364706816aba3e25717850c26c9cd0d89d")
174 %!assert (hash ("sha1", ["abcdbcdecdefdefgefghfghighijhi", ...
175 %! "jkijkljklmklmnlmnomnopnopq"]),
176 %! "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
177 %!assert (hash ("sha1", ["01234567012345670123456701234567", ...
178 %! "01234567012345670123456701234567"]),
179 %! "e0c094e867ef46c350ef54a7f59dd60bed92ae83");
180 %!assert (hash ("sha1", "The quick brown fox jumps over the lazy dog"),
181 %! "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12");
182 
183 ## SHA224 test suite (RFC 3874) and more
184 %!assert (hash ("sha224", ""),
185 %! "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f");
186 %!assert (hash ("sha224", "a"),
187 %! "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5");
188 %!assert (hash ("sha224", "abc"),
189 %! "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7");
190 %!assert (hash ("sha224", ["abcdbcdecdefdefgefghfghighijh", ...
191 %! "ijkijkljklmklmnlmnomnopnopq"]),
192 %! "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525");
193 
194 ## SHA256/384/512 tests (RFC 6234) and more
195 %!assert (hash ("sha256", ""),
196 %! "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
197 %!assert (hash ("sha384", ""),
198 %! ["38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc", ...
199 %! "7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"]);
200 %!assert (hash ("sha512", ""),
201 %! ["cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a", ...
202 %! "921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47", ...
203 %! "417a81a538327af927da3e"]);
204 
205 ## Test special character behavior
206 %!assert <*31689> (hash ("md2", "abc\0"), "5a636d615002a7874ac1c9e9a43361f7")
207 %!assert <*31689> (hash ("md4", "abc\0"), "0ee5201897ecb206c4eaba1d2da5224d")
208 %!assert <*31689> (hash ("md5", "abc\0"), "147a664a2ca9410911e61986d3f0d52a")
209 %!assert <*31689> (hash ("sha1", "abc\0"),
210 %! "686483805ac47ca14e03514f7481a7973b401762")
211 %!assert <*31689> (hash ("sha224", "abc\0"),
212 %! "fbc8e47920e108bb1d0b631d18b36ae9b1549d28362aa15ebe960cfb");
213 %!assert <*31689> (hash ("sha256", "abc\0"),
214 %! "dc1114cd074914bd872cc1f9a23ec910ea2203bc79779ab2e17da25782a624fc");
215 %!assert <*31689> (hash ("sha384", "abc\0"),
216 %! ["eba81f2dfba4ec60d3f786c89d91b08e6c0b63d55986874378e385", ...
217 %! "e6fac587cce7a520ca9437290fe626cbf75c855e17"]);
218 %!assert <*31689> (hash ("sha512", "abc\0"),
219 %! ["7ce05eda233e545a2d5c626862a5ddaafb09b9d8ec3bec08aa458b", ...
220 %! "7c9e7d939d84a57d5a20d8a9002983aabae2457b19c50ba326bf5b", ...
221 %! "081f75b41342f42c3383"]);
222 
223 ## Test equivalence to deprecated md5sum offering file hashing
224 %!test
225 %! tfile = tempname ();
226 %! fid = fopen (tfile, "wb");
227 %! fwrite (fid, "abc\0");
228 %! fclose (fid);
229 %! assert (hash ("md5", fileread (tfile)), "147a664a2ca9410911e61986d3f0d52a");
230 %! unlink (tfile);
231 
232 ## Test bad function calls
233 %!error hash ()
234 %!error hash ("")
235 %!error hash ("", "")
236 %!error hash ("", "", "")
237 %!error hash (1, "")
238 %!error hash ([1, 0; 0, 1], "")
239 %!error hash ("unknown", "")
240 %!error hash ("md5")
241 %!error hash ("sha1")
242 %!error hash ("sha512")
243 */
244 
245 OCTAVE_END_NAMESPACE(octave)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage(void)
Definition: defun-int.h:72
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
std::string hash(hash_fptr hash_fcn, const std::string &str, int result_buf_len)
Definition: lo-hash.cc:45
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219