diff --git a/src/dorkbox/bytes/HashExtensions.kt b/src/dorkbox/bytes/HashExtensions.kt index 71db407..4cd2e04 100644 --- a/src/dorkbox/bytes/HashExtensions.kt +++ b/src/dorkbox/bytes/HashExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021 dorkbox, llc + * Copyright 2023 dorkbox, llc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package dorkbox.bytes +import dorkbox.bytes.Hash.charToBytes16 +import java.awt.SystemColor.text import java.security.MessageDigest import java.security.NoSuchAlgorithmException @@ -25,11 +27,6 @@ object Hash { */ const val version = BytesInfo.version - init { - // Add this project to the updates system, which verifies this class + UUID + version information - dorkbox.updates.Updates.add(Hash::class.java, "f176cecea06e48e1a96d59c08a6e98c3", BytesInfo.version) - } - internal val digest1 = ThreadLocal.withInitial { try { return@withInitial MessageDigest.getInstance("SHA1") @@ -46,6 +43,20 @@ object Hash { } } + /** + * this saves the char array in UTF-16 format of bytes + */ + fun charToBytes16(text: CharArray): ByteArray { + // NOTE: this saves the char array in UTF-16 format of bytes. + val bytes = ByteArray(text.size * 2) + for (i in text.indices) { + bytes[2 * i] = (text[i].code shr 8).toByte() + bytes[2 * i + 1] = text[i].code.toByte() + } + return bytes + } + + val sha1 get() = digest1.get() val sha256 get() = digest256.get() } @@ -66,3 +77,91 @@ fun ByteArray.sha256(): ByteArray { digest.update(this) return digest.digest() } + + +/** + * gets the SHA1 hash of the specified string, as UTF-16 + */ +fun String.sha1(): ByteArray { + val charToBytes = this.toCharArray().charToBytes16() + + val digest: MessageDigest = Hash.digest1.get() + val usernameHashBytes = ByteArray(digest.digestLength) + digest.update(charToBytes, 0, charToBytes.size) + digest.digest(usernameHashBytes) + + return usernameHashBytes +} + +/** + * gets the SHA256 hash of the specified string, as UTF-16 + */ +fun String.sha256(): ByteArray { + val charToBytes = this.toCharArray().charToBytes16() + + val digest: MessageDigest = Hash.digest256.get() + val usernameHashBytes = ByteArray(digest.digestLength) + digest.update(charToBytes, 0, charToBytes.size) + digest.digest(usernameHashBytes) + + return usernameHashBytes +} + +/** + * gets the SHA256 hash + SALT of the string, as UTF-16 + */ +fun String.sha1WithSalt(saltBytes: ByteArray): ByteArray { + val charToBytes = this.toCharArray().charToBytes16() + val userNameWithSalt = charToBytes + saltBytes + + val digest: MessageDigest = Hash.digest1.get() + val usernameHashBytes = ByteArray(digest.digestLength) + digest.update(userNameWithSalt, 0, userNameWithSalt.size) + digest.digest(usernameHashBytes) + + return usernameHashBytes +} + +/** + * gets the SHA256 hash + SALT of the string, as UTF-16 + */ +fun String.sha256WithSalt(saltBytes: ByteArray): ByteArray { + val charToBytes = this.toCharArray().charToBytes16() + val userNameWithSalt = charToBytes + saltBytes + + val digest: MessageDigest = Hash.digest256.get() + val usernameHashBytes = ByteArray(digest.digestLength) + digest.update(userNameWithSalt, 0, userNameWithSalt.size) + digest.digest(usernameHashBytes) + + return usernameHashBytes +} + +/** + * gets the SHA1 hash + SALT of the byte array + */ +fun ByteArray.sha1WithSalt(saltBytes: ByteArray): ByteArray { + val bytesWithSalt = this + saltBytes + + val sha256: MessageDigest = Hash.digest1.get() + val usernameHashBytes = ByteArray(sha256.digestLength) + sha256.update(bytesWithSalt, 0, bytesWithSalt.size) + sha256.digest(usernameHashBytes) + + return usernameHashBytes +} + +/** + * gets the SHA256 hash + SALT of the byte array + */ +fun ByteArray.sha256WithSalt(saltBytes: ByteArray): ByteArray { + val bytesWithSalt = this + saltBytes + + val sha256: MessageDigest = Hash.digest256.get() + val usernameHashBytes = ByteArray(sha256.digestLength) + sha256.update(bytesWithSalt, 0, bytesWithSalt.size) + sha256.digest(usernameHashBytes) + + return usernameHashBytes +} +