Skip to content

Commit

Permalink
feat: regex removal (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
augi authored Jul 15, 2021
1 parent 2024f6b commit c3ff57b
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 31 deletions.
25 changes: 9 additions & 16 deletions core/src/main/scala/com/avast/scala/hashes/package.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package com.avast.scala

import java.util.Base64
import java.util.regex.Pattern

package object hashes {

private val hexAllowedCharactersRegex = Pattern.compile("[^0-9A-Fa-f]")

/**
* Removes all the non-HEX characters from the input string and then transform the remaining HEX characters to byte array.
* So this method never throws an exception.
* Performs a check if the input string has the right count of characters to be a valid HEX string for expectedBytes bytes.
* If so, decodes them, returns None otherwise.
*/
def hex2bytes(hex: String): Array[Byte] = hex2bytesUnchecked(hexAllowedCharactersRegex.matcher(hex).replaceAll(""))
def tryHex2bytes(maybeHex: String, expectedBytes: Int): Option[Array[Byte]] = {
if (maybeHex.length == 2 * expectedBytes) Some(hex2bytes(maybeHex)) else None
}

private def hex2bytesUnchecked(hex: String): Array[Byte] = {
/**
* Transform the input string to a new byte array, supposing all the characters as valid HEX characters (both lower and upper case are accepted).
*/
def hex2bytes(hex: String): Array[Byte] = {
val r = new Array[Byte](hex.length / 2)
var i = 0
while (i < (hex.length / 2)) {
Expand All @@ -30,15 +32,6 @@ package object hashes {
case _ => throw new IllegalArgumentException
}

/**
* Removes all the non-HEX characters from the input string and then performs the check if the remaining characters
* could be decoded to expected bytes. If so, decodes them, returns None otherwise.
*/
def tryHex2bytes(maybeHex: String, expectedBytes: Int): Option[Array[Byte]] = {
val clean = hexAllowedCharactersRegex.matcher(maybeHex).replaceAll("")
if (clean.length == 2 * expectedBytes) Some(hex2bytesUnchecked(clean)) else None
}

/**
* Encodes bytes to lower-case HEX string, optionally with a separator between bytes (so between every two characters).
*/
Expand Down
8 changes: 2 additions & 6 deletions core/src/test/scala/com/avast/scala/hashes/MD5Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ class MD5Test extends AnyFlatSpec with Matchers {
MD5("6a18b3c45107538de9d430f83a6af988").hashCode() shouldBe MD5("6a18b3c45107538de9d430f83a6af988").hashCode()
}

it should "convert MD5 to lower-case" in {
MD5("6A18B3C45107538DE9D430F83A6AF988").toString() shouldBe "6a18b3c45107538de9d430f83a6af988"
}

it should "convert hex value with additional characters" in {
MD5("\"6A18B3C45107538DE9D430F83A6AF988 \"").toString() shouldBe "6a18b3c45107538de9d430f83a6af988"
it should "parse from base64" in {
MD5("ahizxFEHU43p1DD4Omr5iA==").toHexString shouldBe "6a18b3c45107538de9d430f83a6af988"
}
}
5 changes: 0 additions & 5 deletions core/src/test/scala/com/avast/scala/hashes/PackageTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class PackageTest extends AnyFlatSpec with Matchers {
("TRU", 3, None),
("", 1, None),
(" TRU", 3, None),
(" ", 0, Some(Array.emptyByteArray)),
("001991FF", 3, None),
("001991FF", 5, None),
("001991FF", 4, Some(Array(0, 25, 145, 255).map(_.toByte)))).foreach { case (input, expectedBytes, expectedResult) =>
Expand All @@ -36,10 +35,6 @@ class PackageTest extends AnyFlatSpec with Matchers {

Seq(
("001991FF", Array(0, 25, 145, 255).map(_.toByte)),
(" 001991FF ", Array(0, 25, 145, 255).map(_.toByte)),
("uu001991FFuu", Array(0, 25, 145, 255).map(_.toByte)),
("WFTF", Array(255).map(_.toByte)),
("uuuu", Array.emptyByteArray),
("", Array.emptyByteArray)).foreach { case (input, expectedResult) =>
it must s"return expected result from hex2bytes for input '$input' string" in {
hex2bytes(input) shouldBe expectedResult
Expand Down
4 changes: 2 additions & 2 deletions core/src/test/scala/com/avast/scala/hashes/Sha1Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Sha1Test extends AnyFlatSpec with Matchers {
Sha1("0FD08A268F6032CE2A83A17AC8ADCEAF82ADE5E3").toString() shouldBe "0fd08a268f6032ce2a83a17ac8adceaf82ade5e3"
}

it should "convert hex value with additional characters" in {
Sha1("\"0FD08A268F6032CE2A83A17AC8ADCEAF82ADE5E3 \"").toString() shouldBe "0fd08a268f6032ce2a83a17ac8adceaf82ade5e3"
it should "parse from base64" in {
Sha1("D9CKJo9gMs4qg6F6yK3Or4Kt5eM=").toHexString shouldBe "0fd08a268f6032ce2a83a17ac8adceaf82ade5e3"
}
}
4 changes: 2 additions & 2 deletions core/src/test/scala/com/avast/scala/hashes/Sha256Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class Sha256Test extends AnyFlatSpec with Matchers {
Sha256("6A18B3C45107538DE9D430F83A6AF988EDBDDEB4E5A6BDB16F223A2FA37EE446").toString() shouldBe "6a18b3c45107538de9d430f83a6af988edbddeb4e5a6bdb16f223a2fa37ee446"
}

it should "convert hex value with additional characters" in {
Sha256("\"6A18B3C45107538DE9D430F83A6AF988EDBDDEB4E5A6BDB16F223A2FA37EE446 \"").toString() shouldBe "6a18b3c45107538de9d430f83a6af988edbddeb4e5a6bdb16f223a2fa37ee446"
it should "parse from base64" in {
Sha256("ahizxFEHU43p1DD4Omr5iO293rTlpr2xbyI6L6N+5EY=").toHexString shouldBe "6a18b3c45107538de9d430f83a6af988edbddeb4e5a6bdb16f223a2fa37ee446"
}

it should "generate base64 of the same length for random SHA256" in {
Expand Down

0 comments on commit c3ff57b

Please sign in to comment.