;*; Created on 17-Sep-92 at 12:36 AM by James A. Jarboe I V; edit time: 0:40:40 ; ; TBXHSH - Demonstrates bug in TOOLBX hashing routine, ; and a possible solution. Although actually all it shows ; is that the newer hashing routine hashes this sample differently. ; ; Rob/Ken, ; ; After mystic revelations, d/FIX, and 5 cups of expresso, ; the following program will demonstrate how TOOLBX handles it's ; hashing of each ESP field. ; The TBXHSH: routine is what appears to be ESP's hashing routine. ; The IRVHSH: routine was taken from JOBSTS.LIT by Irv Bromberg ; and was used to compute a hash of each display line and not output ; and consume I/O time if no changes where to made to the display ; for a dynamic display of a job's JCB. ; ; The results I get using Ken's magic strings are: ; ; ESP hashing. ; ; String Decimal hash Octal hash ;-------------------------------------------------- ; 16906 = 84280356 501402044 ; 16834 = 84280356 501402044 ; 36906 = 84411492 502002144 ; ; IRV's Hashing. ; ; 16906 = 84321787 501522773 ; 16834 = 84338650 501563732 ; 36906 = 84468088 502160570 ; ; Which does show that the newer hashing routine works differently. ; As to if it is more accurate and has a lessor redundency ; is another question. ; ; [100] 17-Sep-92 by James A. Jarboe IV SEARCH SYS SEARCH SYSSYM DEFINE PRTTAB ROW, COL MOVW #<ROW_8.+COL>, D1 TCRT ENDM VMAJOR = 1 VMINOR = 0 VEDIT = 100. ; 17-Sep-92 ; Demonstrate TOOLBX hashing problem. ; START: PHDR -1,0,PH$REE!PH$REU PRTTAB -1,0 ; Clear screen TYPECR <Testing TOOLBX Hashing routine to demonstrate bug.> CRLF ; Bump line TYPECR <String Hash Hash > CRLF LEA A6, TEST1 ; Index first string. MOV #TSIZ1, D6 ; Set number of chars. CALL DO.IT ; Do hashing and display. LEA A6, TEST2 ; Index second string. MOV #TSIZ2, D6 ; Set number of chars. CALL DO.IT ; Do hashing and display. LEA A6, TEST3 ; Index control string. MOV #TSIZ3, D6 ; Set number of chars. CALL DO.IT ; Do hashing and display. CRLF TYPECR <Now, try IRV's HASHing> CRLF LEA A6, TEST1 ; Index first string. MOV #TSIZ1, D6 ; Set number of chars. CALL DO.ME ; Do hashing and display. LEA A6, TEST2 ; Index second string. MOV #TSIZ2, D6 ; Set number of chars. CALL DO.ME ; Do hashing and display. LEA A6, TEST3 ; Index control string. MOV #TSIZ3, D6 ; Set number of chars. CALL DO.ME ; Do hashing and display. EXIT ; Finito! ; Do hashing and display. ; ; Incoming: ; D6 =: Number of chars to hash ; A6 -> Indexes buffer of string to hash. ; Outgoing: ; D6 =: Hash total of string. ; A6 -> Indexes end of buffer. ; DO.IT: PUSH A6 ; Save buffer address. CALL TBXHSH ; Call hashing routine. MOV D6, D1 ; Save hash total POP A6 ; Restore buffer address. TTYL @A6 ; Output string. TYPE < = > ; Output seperator. DCVT 0, OT$TRM ; Output in decimal. TAB ; OCVT 0,OT$TRM ; Output in current base. CRLF ; Bump line. RTN ; Return to caller. ; Do hashing and display. Using another hashing method. ; ; Incoming: ; D6 =: Number of chars to hash ; A6 -> Indexes buffer of string to hash. ; Outgoing: ; D6 =: Hash total of string. ; A6 -> Indexes end of buffer. ; DO.ME: PUSH A6 ; Save buffer address. CALL IRVHSH ; Call hashing routine. MOV D6, D1 ; Save hash total POP A6 ; Restore buffer address. TTYL @A6 ; Output string. TYPE < = > ; Output seperator. DCVT 0, OT$TRM ; Output in decimal. TAB ; OCVT 0,OT$TRM ; Output in current base. CRLF ; Bump line. RTN ; Return to caller. ; What appears to be TOOLBX's Hashing routine. ; ; Incoming: ; D6 =: Number of characters to hash. ; ; A6 -> Indexes buffer to hash. ; ; Outgoing: ; D6 =: Hash total of field. ; A6 -> Indexes end of buffer. TBXHSH: ; It appears that the first step is to save the number of char in a field ; in the high byte of the low word and then save the total ASCII value ; of the string in the low byte of the low word, then save all of that ; in the high word. MOV D6, D7 ; Save number of chars. BEQ 99$ ; Opps..none there..quit. SUB #1, D7 ; Dbf adjust count. ASL D6, #8. ; Mul * 256. SAVE A6, D7 ; Save address of buffer & count. 10$: ADDB (A6)+, D6 ; Add ascii value byte to number. DBF D7, 10$ ; For all chars. ; The following code represents what appears to be adding in ; the ESP field's Read and Write security level. ; ; Which for most of the time is a constant unless it is changed in ; an ESP screen. While changing this value would create a different ; hash total than a previous one with different field security levels, it ; would create the same hash total on the next pass if the values for Read ; and Write security remain the same. Soooo for this example we assume ; that the Read and Write security is 0. Thus we comment it out because ; any number + 0 is still that number. ;; ADDB 22(A3), D6 ; Add read security value. ;; ADDB 23(A3), D6 ; Add Write security value. REST A6, D7 ; Restore buffer address & count. SWAP D6 ; Swap Words. 20$: CLR D1 ; Preclear hasher. MOVB (A6)+, D1 ; Get next char. XORW D1, D6 ; Shake it. ROLW D6, #1 ; Roll it. DBF D7, 20$ ; And try again. 99$: RTN ; Return to caller. ;IRVHSH: ; ; Part of this hashing routine was taken from JOBSTS.LIT by Irv Bromberg ; off the AMUS Newtork. It always appeared to work without any problems. ; I am sure some mathmematicion could verify it's redundency occurance of ; likely hash matches for different string values. ; ; Incoming: ; D6 =: Number of characters to hash. ; ; A6 -> Indexes buffer to hash. ; ; Outgoing: ; D6 =: Hash total of field. ; A6 -> Indexes end of buffer. IRVHSH: MOV D6, D7 ; Save number of chars. BEQ 99$ ; Opps..none there..quit. SUB #1, D7 ; Dbf adjust count. ASL D6, #8. ; Mul * 256. SAVE A6, D7 ; Save address of buffer & count. 10$: ADDB (A6)+, D6 ; Add ascii value byte to number. DBF D7, 10$ ; For all chars. ;; ADDB 22(A3), D6 ; Add read security value. ;; ADDB 23(A3), D6 ; Add Write security value. REST A6, D7 ; Restore buffer address & count. SWAP D6 ; Swap Words. CLR D1 ; Preclear hasher. ; Here's a modified adaptation of Irv's hashing routine. Actually he only ; stored and checked the resulting word value. Assuming that ESP stores this ; as a long word, we just tack it on to what is done above since it appears ; that the TOOLBX version does about the same thing. ; 20$: MOVB (A6)+, D1 ; Get next char. LSLW D1, #8. ; Shift to high byte. XORW D1, D6 ; Rattle. PUSH D7 ; Save current char count. MOVW #<8.-1>, D7 ; Set number of bits (dbf adj). 30$: TSTW D6 ; Is hash word negative? BMI 40$ ; Yes.. LSLW D6, #1 ; No..shift. BR 50$ ; Try next bits. 40$: LSLW D6, #1 ; Shift. XORW #^O10041, D6 ; Rattle. 50$: DBF D7, 30$ ; Do all bits. POP D7 ; Restore current count. DBF D7, 20$ ; Do all chars. 99$: RTN ; Return to caller. ; Strings ; TEST1: ASCII /16906/ ; Ken's magic string 1. TSIZ1=.-TEST1 ; Size of string. BYTE 0 ; TEST2: ASCII /16834/ ; Ken's magic string 2. TSIZ2=.-TEST2 ; Size of string. BYTE 0 ; TEST3: ASCII /36906/ ; Control string. TSIZ3=.-TEST3 ; Size of string. BYTE 0 ; EVEN END