The SHA-1 algorithm always generates a 160-bit (20-byte) hash; you cannot vary the size of it.
You are seeing 40 bytes because you are using LENGTH
which expects the first argument to be a string and the RAW
is being implicitly converted to a hexadecimal string with two hexadecimal characters per byte which doubles the length.
If you use UTL_RAW.LENGTH
to generate the output then you will see the byte length without converting to a string.
If you only want an 8-bytes then you could use UTL_RAW.SUBSTR
to take the first 8-bytes of the SHA-1 hash:
SELECT STANDARD_HASH(x, 'SHA1') AS hash,
UTL_RAW.LENGTH(STANDARD_HASH(x, 'SHA1')) AS len,
UTL_RAW.SUBSTR(STANDARD_HASH(x, 'SHA1'), 1, 8) AS byte8_hash,
UTL_RAW.LENGTH(UTL_RAW.SUBSTR(STANDARD_HASH(x, 'SHA1'), 1, 8)) AS byte8_len
FROM table_name
Which, for the sample data:
CREATE TABLE table_name (x) AS
SELECT 'aa' x FROM DUAL UNION ALL
SELECT 'bb' x FROM DUAL UNION ALL
SELECT 'cc' x FROM DUAL
Outputs:
HASH |
LEN |
BYTE8_HASH |
BYTE8_LEN |
0xE0C9035898DD52FC65C41454CEC9C4D2611BFB37 |
20 |
0xE0C9035898DD52FC |
8 |
0x9A900F538965A426994E1E90600920AFF0B4E8D2 |
20 |
0x9A900F538965A426 |
8 |
0xBDB480DE655AA6EC75CA058C849C4FAF3C0F75B1 |
20 |
0xBDB480DE655AA6EC |
8 |
(Note: The risk of hash-collisions will be greater with an 8-byte hash compared to a 20-byte hash but, assuming that the original hash function is sufficiently random, truncating a longer hash to 8-bytes should not increase the hash-collisions when compared to directly generating an 8-byte hash.)
fiddle