Skip to content

Instantly share code, notes, and snippets.

@LongClipeus
Last active March 13, 2024 11:54
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save LongClipeus/84db46e7d9714f67c4cbc40a67c8be1e to your computer and use it in GitHub Desktop.
Save LongClipeus/84db46e7d9714f67c4cbc40a67c8be1e to your computer and use it in GitHub Desktop.
How to generate checksum hash for a file in Kotlin
import StringUtils.encodeHex
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.security.MessageDigest
object HashUtils {
const val STREAM_BUFFER_LENGTH = 1024
fun getCheckSumFromFile(digest: MessageDigest, filePath: String): String {
val file = File(filePath)
return getCheckSumFromFile(digest, file)
}
fun getCheckSumFromFile(digest: MessageDigest, file: File): String {
val fis = FileInputStream(file)
val byteArray = updateDigest(digest, fis).digest()
fis.close()
val hexCode = encodeHex(byteArray, true)
return String(hexCode)
}
/**
* Reads through an InputStream and updates the digest for the data
*
* @param digest The MessageDigest to use (e.g. MD5)
* @param data Data to digest
* @return the digest
*/
private fun updateDigest(digest: MessageDigest, data: InputStream): MessageDigest {
val buffer = ByteArray(STREAM_BUFFER_LENGTH)
var read = data.read(buffer, 0, STREAM_BUFFER_LENGTH)
while (read > -1) {
digest.update(buffer, 0, read)
read = data.read(buffer, 0, STREAM_BUFFER_LENGTH)
}
return digest
}
}
import MessageDigestAlgorithm
import java.security.MessageDigest
fun main() {
var file = File(":/storage/sdcard0/DCIM/Camera/1414240995236.jpg")
val checkSumSha256 = HashUtils.getCheckSumFromFile(
MessageDigest.getInstance(MessageDigestAlgorithm.SHA_256),
file
)
}
object MessageDigestAlgorithm {
const val MD2 = "MD2"
const val MD5 = "MD5"
const val SHA_1 = "SHA-1"
const val SHA_224 = "SHA-224"
const val SHA_256 = "SHA-256"
const val SHA_384 = "SHA-384"
const val SHA_512 = "SHA-512"
const val SHA_512_224 = "SHA-512/224"
const val SHA_512_256 = "SHA-512/256"
const val SHA3_224 = "SHA3-224"
const val SHA3_256 = "SHA3-256"
const val SHA3_384 = "SHA3-384"
const val SHA3_512 = "SHA3-512"
}
object StringUtils {
/**
* Used to build output as Hex
*/
private val DIGITS_LOWER =
charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')
/**
* Used to build output as Hex
*/
private val DIGITS_UPPER =
charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F')
/**
* Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
* The returned array will be double the length of the passed array, as it takes two characters to represent any
* given byte.
*
* @param data a byte[] to convert to Hex characters
* @param toLowerCase `true` converts to lowercase, `false` to uppercase
* @return A char[] containing hexadecimal characters in the selected case
*/
fun encodeHex(data: ByteArray, toLowerCase: Boolean): CharArray {
return encodeHex(data, if (toLowerCase) DIGITS_LOWER else DIGITS_UPPER)
}
/**
* Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
* The returned array will be double the length of the passed array, as it takes two characters to represent any
* given byte.
*
* @param data a byte[] to convert to Hex characters
* @param toDigits the output alphabet (must contain at least 16 chars)
* @return A char[] containing the appropriate characters from the alphabet
* For best results, this should be either upper- or lower-case hex.
*/
fun encodeHex(data: ByteArray, toDigits: CharArray): CharArray {
val l = data.size
val out = CharArray(l shl 1)
// two characters form the hex value.
var i = 0
var j = 0
while (i < l) {
out[j++] = toDigits[0xF0 and data[i].toInt() ushr 4]
out[j++] = toDigits[0x0F and data[i].toInt()]
i++
}
return out
}
}
@ArnyminerZ
Copy link

Works like a charm, thank you very much 🚀

@david-perez
Copy link

@LongClipeus I'd like to reuse this for a project. Under what license is this gist's content available?

@ArnyminerZ
Copy link

@david-perez well, I imagine that if your project is open source there should be no issue. If your code is enclosed, @LongClipeus has the word 🤷🏼

@LongClipeus
Copy link
Author

@ArnyminerZ @david-perez I'm glad this little piece of code was helpful to both of you. Feel free to use it in your projects.

Most of the code in this sample I took from Apache Commons Codec and converted to Kotlin.

@mhrohani1385
Copy link

Thank you very much!
This is useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment