[Home] [Help]
PACKAGE BODY: APPS.FND_HASH_PKG
Source
1 package body FND_HASH_PKG as
2 /* $Header: AFCPHSHB.pls 115.5 2003/09/20 15:32:23 ckclark ship $ */
3
4 type inttab is table of binary_integer index by binary_integer;
5 type numtab is table of number index by binary_integer;
6
7 CRCARRAY numtab;
8 CRCFLAG boolean := null;
9
10 /*
11 ** Returns a table of XOR results for 4-bit nibbles.
12 ** This is needed because PL/SQL has no way to do XOR natively,
13 ** so a lookup table is used. A table of 8-bit bytes would
14 ** be 65536 entries long, so byte values are XORed in 4-bit
15 ** nibbles, and a small table of 256 results is sufficient.
16 */
17 function HEXNIBBLE return varchar2 is
18 begin
19 return('0123456789ABCDEF'||
20 '1032547698BADCFE'||
21 '23016745AB89EFCD'||
22 '32107654BA98FEDC'||
23 '45670123CDEF89AB'||
24 '54761032DCFE98BA'||
25 '67452301EFCDAB89'||
26 '76543210FEDCBA98'||
27 '89ABCDEF01234567'||
28 '98BADCFE10325476'||
29 'AB89EFCD23016745'||
30 'BA98FEDC32107654'||
31 'CDEF89AB45670123'||
32 'DCFE98BA54761032'||
33 'EFCDAB8967452301'||
34 'FEDCBA9876543210');
35 end HEXNIBBLE;
36
37 /*
38 ** Compute the XOR of two integers and return an
39 ** integer result, modulo 32 bits.
40 */
41 function XOR32(B1 in number, B2 in number)
42 return number
43 is
44 A1 number;
45 A2 number;
46 NIBBLE1 number;
47 NIBBLE2 number;
48 NIBBLE3 number;
49 NIBBLE4 number;
50 NIBBLE5 number;
51 NIBBLE6 number;
52 NIBBLE7 number;
53 NIBBLE8 number;
54 HEXTABLE varchar2(256);
55 CHARBIN varchar2(16);
56 begin
57 A1 := B1;
58 A2 := B2;
59 NIBBLE1 := mod(A1, 16) * 16 + mod(A2, 16) + 1;
60 A1 := trunc(A1/16);
61 A2 := trunc(A2/16);
62 NIBBLE2 := mod(A1, 16) * 16 + mod(A2, 16) + 1;
63 A1 := trunc(A1/16);
64 A2 := trunc(A2/16);
65 NIBBLE3 := mod(A1, 16) * 16 + mod(A2, 16) + 1;
66 A1 := trunc(A1/16);
67 A2 := trunc(A2/16);
68 NIBBLE4 := mod(A1, 16) * 16 + mod(A2, 16) + 1;
69 A1 := trunc(A1/16);
70 A2 := trunc(A2/16);
71 NIBBLE5 := mod(A1, 16) * 16 + mod(A2, 16) + 1;
72 A1 := trunc(A1/16);
73 A2 := trunc(A2/16);
74 NIBBLE6 := mod(A1, 16) * 16 + mod(A2, 16) + 1;
75 A1 := trunc(A1/16);
76 A2 := trunc(A2/16);
77 NIBBLE7 := mod(A1, 16) * 16 + mod(A2, 16) + 1;
78 A1 := trunc(A1/16);
79 A2 := trunc(A2/16);
80 NIBBLE8 := mod(A1, 16) * 16 + mod(A2, 16) + 1;
81
82 HEXTABLE := HEXNIBBLE;
83
84 CHARBIN := '0123456789ABCDEF';
85
86 return((instr(CHARBIN,substr(HEXTABLE,NIBBLE1,1))-1) +
87 (instr(CHARBIN,substr(HEXTABLE,NIBBLE2,1))-1)*16 +
88 (instr(CHARBIN,substr(HEXTABLE,NIBBLE3,1))-1)*16*16 +
89 (instr(CHARBIN,substr(HEXTABLE,NIBBLE4,1))-1)*16*16*16 +
90 (instr(CHARBIN,substr(HEXTABLE,NIBBLE5,1))-1)*16*16*16*16 +
91 (instr(CHARBIN,substr(HEXTABLE,NIBBLE6,1))-1)*16*16*16*16*16 +
92 (instr(CHARBIN,substr(HEXTABLE,NIBBLE7,1))-1)*16*16*16*16*16*16 +
93 (instr(CHARBIN,substr(HEXTABLE,NIBBLE8,1))-1)*16*16*16*16*16*16*16.0);
94
95 end XOR32;
96
97 /*
98 ** Compute an array of 32-bit CRC values
99 */
100 procedure CRCINIT
101 is
102 A binary_integer;
103 B binary_integer;
104 X number;
105 begin
106 if (CRCFLAG is null) then
107 for A in 1..256 loop
108 X := A - 1;
109 for B in 1..8 loop
110 if (MOD(X, 2) = 1) then
111 X := XOR32(trunc(X/2), 3988292384);
112 else
113 X := trunc(X/2);
114 end if;
115 end loop;
116 CRCARRAY(A) := mod(X, 4294967296);
117 end loop;
118 CRCFLAG := TRUE;
119 end if;
120 end CRCINIT;
121
122 function CRC32(DATASTRING in varchar2)
123 return number
124 is
125 DATAINT inttab;
126 SLEN binary_integer;
127 DLEN binary_integer;
128 KLOC binary_integer;
129 KTEMP binary_integer;
130 TINDEX binary_integer;
131 CRCRESULT number;
132 begin
133
134 -- Initialize CRC table
135 CRCINIT;
136
137 -- Turn the data string into a series of binary integer byte values
138 DLEN := 0;
139 SLEN := length(DATASTRING);
140 for KLOC in 1..SLEN loop
141 KTEMP := ascii(substr(DATASTRING,KLOC,1));
142 if (KTEMP >= 256 * 256 * 256) then
143 DATAINT(DLEN + 4) := mod(KTEMP, 256);
144 KTEMP := (KTEMP - mod(KTEMP, 256))/256;
145 DATAINT(DLEN + 3) := mod(KTEMP, 256);
146 KTEMP := (KTEMP - mod(KTEMP, 256))/256;
147 DATAINT(DLEN + 2) := mod(KTEMP, 256);
148 KTEMP := (KTEMP - mod(KTEMP, 256))/256;
149 DATAINT(DLEN + 1) := mod(KTEMP, 256);
150 DLEN := DLEN + 4;
151 elsif (KTEMP >= 256 * 256) then
152 DATAINT(DLEN + 3) := mod(KTEMP, 256);
153 KTEMP := (KTEMP - mod(KTEMP, 256))/256;
154 DATAINT(DLEN + 2) := mod(KTEMP, 256);
155 KTEMP := (KTEMP - mod(KTEMP, 256))/256;
156 DATAINT(DLEN + 1) := mod(KTEMP, 256);
157 DLEN := DLEN + 3;
158 elsif (KTEMP >= 256) then
159 DATAINT(DLEN + 2) := mod(KTEMP, 256);
160 KTEMP := (KTEMP - mod(KTEMP, 256))/256;
161 DATAINT(DLEN + 1) := mod(KTEMP, 256);
162 DLEN := DLEN + 2;
163 else
164 DLEN := DLEN + 1;
165 DATAINT(DLEN) := mod(KTEMP, 256);
166 end if;
167 end loop;
168
169 -- Loop through the data string and compute the CRC result
170 CRCRESULT := 4294967295;
171 for KLOC in 1..DLEN loop
172 TINDEX := mod(XOR32(CRCRESULT, DATAINT(KLOC)), 256) + 1;
173 CRCRESULT := XOR32(CRCARRAY(TINDEX), trunc(CRCRESULT/256));
174 end loop;
175
176 CRCRESULT := XOR32(CRCRESULT, 4294967295);
177
178 return(CRCRESULT);
179 end CRC32;
180
181 end FND_HASH_PKG;