-
Notifications
You must be signed in to change notification settings - Fork 18
/
xls_sheetpass_hash.cxx
85 lines (68 loc) · 2.42 KB
/
xls_sheetpass_hash.cxx
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
82
83
84
#include <vector>
#include <stdio.h>
using namespace std;
typedef unsigned char sal_uInt8;
typedef unsigned short sal_uInt16;
/*
Reference: Office Open XML Part4 - Markup Language Reference, Section
3.3.1.81 sheetProtection (Sheet Protection Options)
Specifies the hash of the password required for editing this worksheet. This
protection is optional and may be ignored by applications that choose not to
support this functionality. The hash is generated from an 8-bit wide
character. 16-bit Unicode characters must be converted down to 8 bits before
the hash is computed, using the logic defined in the revisionsPassword
attribute of §3.2.29. The resulting value is hashed using the algorithm
defined below.
[Note: An example algorithm to hash the user input into the value stored is
as follows:
// Function Input:
// szPassword: NULL terminated C-Style string
// cchPassword: The number of characters in szPassword (not
including the NULL terminator)
WORD GetPasswordHash(const CHAR *szPassword, int cchPassword) {
WORD wPasswordHash;
const CHAR *pch;
wPasswordHash = 0;
if (cchPassword > 0)
{
pch = &szPassword[cchPassword];
while (pch-- != szPassword)
{
wPasswordHash = ((wPasswordHash >> 14) &
0x01) | ((wPasswordHash << 1) & 0x7fff);
wPasswordHash ^= *pch;
}
wPasswordHash ^= (0x8000 | ('N' << 8) | 'K');
}
return(wPasswordHash);
}
end note]
*/
sal_uInt16 getPasswordHash(const char* szPassword)
{
sal_uInt16 cchPassword = strlen(szPassword);
sal_uInt16 wPasswordHash = 0;
if (!cchPassword)
return wPasswordHash;
const char* pch = &szPassword[cchPassword];
while (pch-- != szPassword)
{
wPasswordHash = ((wPasswordHash >> 14) & 0x01) |
((wPasswordHash << 1) & 0x7fff);
wPasswordHash ^= *pch;
}
wPasswordHash = ((wPasswordHash >> 14) & 0x01) |
((wPasswordHash << 1) & 0x7fff);
wPasswordHash ^= (0x8000 | ('N' << 8) | 'K');
wPasswordHash ^= cchPassword;
return wPasswordHash;
}
int main (int argc, char** argv)
{
if (argc < 2)
exit(1);
printf("input password = %s\n", argv[1]);
sal_uInt16 hash = getPasswordHash(argv[1]);
printf("hash = %4.4X\n", hash);
return 0;
}