MD5 and SHA-256 in Java, Kotlin and Android

Carvia Tech | October 29, 2019 | 3 min read | 3 views


In this article we will discuss different options to compute MD5 (or theoretically any other Hash Function such as SHA-1, SHA-256) using Java, Android and Kotlin.

MD5 is widely used hash function (cryptographically weak) that produces 128 bit hash value. It is mostly used as a checksum to verify data integrity, but only against unintentional corruption. It is not used for security purpose anymore because it suffer from extensive vulnerabilities(Collision and Preimage vulnerabilities specifically).

1. Java implementation: DatatypeConverter

Java provides MessageDigest class that provides applications the functionality of a message digest algorithm, such as MD5, SHA-1 or SHA-256. Message digests are secure one-way hash functions that take arbitrary-sized data and output a fixed-length hash value.

Using Java without external library
import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

class Utils {

    public String md5(String input) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(input.getBytes());
        byte[] digest = md.digest();
        return DatatypeConverter.printHexBinary(digest).toUpperCase();
    }
}

There are other ways also, for example using apache common codecs to compute the hash values, but we will not explore those options here.

2. Using String.format

The underlying algorithm is same but bytes to hexadecimal conversion in this case is done using String.format function instead of DatatypeConverter.

fun String.toMD5(): String {
    val bytes = MessageDigest.getInstance("MD5").digest(this.toByteArray())
    return bytes.toHex()    (1)
}

fun ByteArray.toHex(): String {
    return joinToString("") { "%02x".format(it) }   (2)
}
1 This calls the extension function created on ByteArray
2 02x instructs String format function to print each byte in Hexadecimal format making sure output is padded with 0 in-case of insufficient characters.

Now we can use the below syntax to calculate md5 on any string:

val hash = "foo-bar".toMD5()
Reference

3. Kotlin extension function

We can write extension functions in Kotlin that adds md5() as the function to String class.

Writing extension function in kotlin
import java.math.BigInteger
import java.security.MessageDigest

fun String.md5(): String {
    val md = MessageDigest.getInstance("MD5")
    return BigInteger(1, md.digest(toByteArray())).toString(16).padStart(32, '0')
}

Now we can call this extension function to compute md5 on any arbitrary string value.

Using extension function
val input = "this is a dummy string"
val md5 = input.md5()
println("computed md5 value is $md5")

4. Normal Kotlin function

We can write a normal function in Kotlin that computes MD5 or any other hash using MessageDigest class.

import java.security.MessageDigest
import javax.xml.bind.DatatypeConverter

object Utils {

    fun sha1(input: String) = hashString("SHA-1", input)
    fun md5(input: String) = hashString("MD5", input)

    private fun hashString(type: String, input: String): String {
        val bytes = MessageDigest
                .getInstance(type)
                .digest(input.toByteArray())
        return DatatypeConverter.printHexBinary(bytes).toUpperCase()
    }
}

The above class can be used to compute any type of hash supported by underlying JVM implementation like, SHA-1, SHA-256, MD5, etc.

5. Android Kotlin implementation

DatatypeConverter class is not available in Android, so we can use the below function to convert a given byteArray to hexadecimal format in Android.

const val HEX_CHARS = "0123456789ABCDEF".toCharArray()

fun printHexBinary(data: ByteArray): String {
    val r = StringBuilder(data.size * 2)
    data.forEach { b ->
        val i = b.toInt()
        r.append(HEX_CHARS[i shr 4 and 0xF])
        r.append(HEX_CHARS[i and 0xF])
    }
    return r.toString()
}

6. Using Apache Commons

We can use Apache Common Codec to calculate MD5 Hash value in single line of code. First of all we need to add the below dependency to our build.gradle file.

build.gradle
// https://mvnrepository.com/artifact/commons-codec/commons-codec
compile group: 'commons-codec', name: 'commons-codec', version: '1.13'

If you are using maven, then do it this way:

pom.xml
<!-- https://search.maven.org/remotecontent?filepath=commons-codec/commons-codec/1.13/commons-codec-1.12.jar -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.13</version>
</dependency>

Now, we can use DigestUtils to calculate md5 hash for any string.

DigestUtils
import org.apache.commons.codec.digest.DigestUtils;

public class Util {

    public static String md5() {
        return DigestUtils.md5Hex("foo bar").toUpperCase();
    }
}

7. Other options

Google guava can also be used to calculate checksums and SHA.


Top articles in this category:
  1. Citibank Java developer interview questions
  2. Top 50 Multi-threading Java Interview Questions for Investment Bank
  3. Goldman Sachs Java Interview Questions for Senior Developer
  4. RBS Java Programming Interview Questions
  5. ION Trading Java Interview Questions
  6. Top 20 Java Concurrency Interview Questions and Answers
  7. BlackRock Top Java Interview Questions: Investment Banking Domain



Find more on this topic:
Java Interviews image
Java Interviews

Interview - Product Companies, eCommerce Companies, Investment Banking, Healthcare Industry, Service Companies and Startups.

Last updated 1 week ago


Recommended books for interview preparation:

This website uses cookies to ensure you get the best experience on our website. more info