2.2.51.2 ComputeHashDBCS Method

The DBCS implementation of the hash algorithm uses the default lookup table for all locales.

The ComputeHashDBCS method uses the named constants defined in the LocaleNames (section 2.2.51.4), PrimaryLookupTables (section 2.2.51.5), and DBCS Substitution Tables (section 2.2.51.6) sections.

Set the substitution table and the character range boundaries based on the locale ID and define the character ranges that contain two-byte characters. The Korean and Chinese character tables have two-byte characters only within a single range of character values, so the second range is empty.

 SET LookupTable to US_English_1252
 SET PrimaryLocale to the Logical AND of LocaleID and 0x000003FF
  
 COMMENT  This method MUST only be called when PrimaryLocale 
         is LocaleJapanese, LocaleKorean, or LocaleChinese.
  
 CASE PrimaryLocale OF
  
     LocaleJapanese:      SET SubstitutionTable to WJapanese
                                  SET EncodingMask to 0x00400000
                                  SET LowerRangeStart to 0x80
                                SET LowerRangeEnd to 0xA0
                                SET UpperRangeStart to 0xE0
                                SET UpperRangeEnd to 0xFF
  
     LocaleKorean:       SET SubstitutionTable to WKorean
                                  SET EncodingMask to 0x00500000
                                SET LowerRangeStart to 0x81
                                SET LowerRangeEnd to 0xFE
                                SET UpperRangeStart to 0xFE
                                SET UpperRangeEnd to 0xFE
  
     LocaleChinese:      SET UpperRangeStart to 0xFE 
                                SET UpperRangeEnd to 0xFE
  
                  SET SecondaryLocale to the lower 16 bits of LocaleID
                  COMPUTE SecondaryLocale AS SecondaryLocale divided by 1024
  
                  IF SecondaryLocale is SecondaryLocaleChineseTraditional
          OR SecondaryLocale is SecondaryLocaleChineseHongKong THEN
  
                  SET SubstitutionTable to WChineseTraditional
             SET EncodingMask to 0x00700000
                  SET LowerRangeStart to 0x81
                  SET LowerRangeEnd to 0xFE
           ELSE
                  SET SubstitutionTable to WChineseSimplified
             SET EncodingMask to 0x00600000
                  SET LowerRangeStart to 0xA1
                  SET LowerRangeEnd to 0xFE
         ENDIF
     
 ENDCASE
  
 COMMENT  Initialize hash accumulator with a predefined value.
 COMMENT  Initialize byte index and loop flag.
  
 SET HashAccumulator to 0x0DEADBEE
 SET ByteIndex to refer to the first byte in Name
 SET ByteInName to the value of the byte indexed by ByteIndex
 SET Break to False
  
 COMMENT  Step through the characters in the string, multiplying 
            the accumulator by 37 at each step and adding a value 
            specified by the value of the character.
  
 REPEAT
     
                  COMMENT  Store the current byte or exit the loop.
  
     IF the value of ByteInName is zero THEN
                         SET Break to True
                  ELSE
                  SET TempChar to the value of ByteInName
           ENDIF
  
     COMMENT  Increment the byte index.  If the previous byte 
               was the first byte of a DBCS two-byte character, 
               compute the DBCS character value and increment
              the byte index again.
  
     IF Break is False THEN
                         INCREMENT ByteIndex to refer to the next byte in Name
         SET ByteInName to 
              the value of the byte indexed by ByteIndex
  
         IF (TempChar >= LowerRangeStart AND 
                 TempChar <= LowerRangeEnd) 
                                       OR (TempChar >= UpperRangeStart AND 
                      TempChar <= UpperRangeEnd) THEN
  
             COMMENT  If the second byte of the DBCS character
                          is zero, ignore the character and 
                          exit the loop.
  
             IF the value of ByteInName is zero THEN
                                             SET Break to True                               
             ELSE
                                             COMPUTE TempChar as TempChar 
                                multiplied by 256
                                             COMPUTE TempChar as the value of ByteInName
                               added to TempChar
                                             INCREMENT ByteIndex to refer 
                              to the next byte in Name
                 SET ByteInName to the value of the byte 
                     indexed by ByteIndex
                                       ENDIF
  
                         ENDIF
                  ENDIF
  
           IF Break is False THEN
  
         COMMENT  If the character has an upper byte, replace 
             its value with the appropriate value from a 
             Locale-specified substitution table.
         COMMENT  If the upper byte is nonzero after substitution,
             update the hash accumulator using its value.
  
         IF TempChar > 255
  
                                       CALL MapDBChar 
                                             WITH TempChar, SubstitutionTable 
                                              RETURNING TempChar
  
             SET HighByte to the upper byte of TempChar
                                       IF HighByte is not 0
                                             COMPUTE HashAccumulator as HashAccumulator 
                        multiplied by 37, allowing unsigned 32 bit 
                         overflows
                                             COMPUTE HashAcculumator as LookupTable 
                         (HighByte) added to HashAccumulator, 
                         allowing unsigned 32 bit overflows
                                       ENDIF
                         ENDIF
  
         COMMENT  Update the hash accumulator using the value of 
                 a one-byte character or the lower byte of a 
                 two-byte character.
  
                         SET LowByte to the lower byte of TempChar
         COMPUTE HashAccumulator as HashAccumulator 
                multiplied by 37, allowing unsigned 
                32 bit overflows
                         COMPUTE HashAcculumator as LookupTable 
               (LowByte) added to HashAccumulator, allowing 
               unsigned 32 bit overflows
                  ENDIF
  
 UNTIL Break is True
  
 COMPUTE HashAccumulator as the remainder when HashAccumulator is
     divided by 0x0001003F
 COMPUTE HashAccumulator as the bitwise AND of HashAccumulator and
     0x0000FFFF
 COMPUTE HashAccumulator as the bitwise OR of HashAccumulator and
     EncodingMask
  
 RETURN HashAccumulator as a 32-bit unsigned integer