wolffd@0
|
1 function h = hash(inp,meth)
|
wolffd@0
|
2 % HASH - Convert an input variable into a message digest using any of
|
wolffd@0
|
3 % several common hash algorithms
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % USAGE: h = hash(inp,'meth')
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % inp = input variable, of any of the following classes:
|
wolffd@0
|
8 % char, uint8, logical, double, single, int8, uint8,
|
wolffd@0
|
9 % int16, uint16, int32, uint32, int64, uint64
|
wolffd@0
|
10 % h = hash digest output, in hexadecimal notation
|
wolffd@0
|
11 % meth = hash algorithm, which is one of the following:
|
wolffd@0
|
12 % MD2, MD5, SHA-1, SHA-256, SHA-384, or SHA-512
|
wolffd@0
|
13 %
|
wolffd@0
|
14 % NOTES: (1) If the input is a string or uint8 variable, it is hashed
|
wolffd@0
|
15 % as usual for a byte stream. Other classes are converted into
|
wolffd@0
|
16 % their byte-stream values. In other words, the hash of the
|
wolffd@0
|
17 % following will be identical:
|
wolffd@0
|
18 % 'abc'
|
wolffd@0
|
19 % uint8('abc')
|
wolffd@0
|
20 % char([97 98 99])
|
wolffd@0
|
21 % The hash of the follwing will be different from the above,
|
wolffd@0
|
22 % because class "double" uses eight byte elements:
|
wolffd@0
|
23 % double('abc')
|
wolffd@0
|
24 % [97 98 99]
|
wolffd@0
|
25 % You can avoid this issue by making sure that your inputs
|
wolffd@0
|
26 % are strings or uint8 arrays.
|
wolffd@0
|
27 % (2) The name of the hash algorithm may be specified in lowercase
|
wolffd@0
|
28 % and/or without the hyphen, if desired. For example,
|
wolffd@0
|
29 % h=hash('my text to hash','sha256');
|
wolffd@0
|
30 % (3) Carefully tested, but no warranty. Use at your own risk.
|
wolffd@0
|
31 % (4) Michael Kleder, Nov 2005
|
wolffd@0
|
32 %
|
wolffd@0
|
33 % EXAMPLE:
|
wolffd@0
|
34 %
|
wolffd@0
|
35 % algs={'MD2','MD5','SHA-1','SHA-256','SHA-384','SHA-512'};
|
wolffd@0
|
36 % for n=1:6
|
wolffd@0
|
37 % h=hash('my sample text',algs{n});
|
wolffd@0
|
38 % disp([algs{n} ' (' num2str(length(h)*4) ' bits):'])
|
wolffd@0
|
39 % disp(h)
|
wolffd@0
|
40 % end
|
wolffd@0
|
41
|
wolffd@0
|
42 inp=inp(:);
|
wolffd@0
|
43 % convert strings and logicals into uint8 format
|
wolffd@0
|
44 if ischar(inp) || islogical(inp)
|
wolffd@0
|
45 inp=uint8(inp);
|
wolffd@0
|
46 else % convert everything else into uint8 format without loss of data
|
wolffd@0
|
47 inp=typecast(inp,'uint8');
|
wolffd@0
|
48 end
|
wolffd@0
|
49
|
wolffd@0
|
50 % verify hash method, with some syntactical forgiveness:
|
wolffd@0
|
51 meth=upper(meth);
|
wolffd@0
|
52 switch meth
|
wolffd@0
|
53 case 'SHA1'
|
wolffd@0
|
54 meth='SHA-1';
|
wolffd@0
|
55 case 'SHA256'
|
wolffd@0
|
56 meth='SHA-256';
|
wolffd@0
|
57 case 'SHA384'
|
wolffd@0
|
58 meth='SHA-384';
|
wolffd@0
|
59 case 'SHA512'
|
wolffd@0
|
60 meth='SHA-512';
|
wolffd@0
|
61 otherwise
|
wolffd@0
|
62 end
|
wolffd@0
|
63 algs={'MD2','MD5','SHA-1','SHA-256','SHA-384','SHA-512'};
|
wolffd@0
|
64 if isempty(strmatch(meth,algs,'exact'))
|
wolffd@0
|
65 error(['Hash algorithm must be ' ...
|
wolffd@0
|
66 'MD2, MD5, SHA-1, SHA-256, SHA-384, or SHA-512']);
|
wolffd@0
|
67 end
|
wolffd@0
|
68
|
wolffd@0
|
69 % create hash
|
wolffd@0
|
70 x=java.security.MessageDigest.getInstance(meth);
|
wolffd@0
|
71 x.update(inp);
|
wolffd@0
|
72 h=typecast(x.digest,'uint8');
|
wolffd@0
|
73 h=dec2hex(h)';
|
wolffd@0
|
74 if(size(h,1))==1 % remote possibility: all hash bytes < 128, so pad:
|
wolffd@0
|
75 h=[repmat('0',[1 size(h,2)]);h];
|
wolffd@0
|
76 end
|
wolffd@0
|
77 h=lower(h(:)');
|
wolffd@0
|
78 clear x
|
wolffd@0
|
79 return |