DBA Data[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;