From 52fe3cf3c87edb220831232bfd3325690920ec30 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 11:40:05 +1200 Subject: [PATCH] Change from MD5 to Checksum (Adler32) for json content dirty detection --- .../server/deploy/BeanPropertyJsonMapper.java | 12 +++++++---- .../ebeaninternal/server/util/Checksum.java | 20 +++++++++++++++++++ .../io/ebeaninternal/server/util/Md5.java | 1 - .../server/util/ChecksumTest.java | 18 +++++++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java create mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index 38c9ebb9f..747df5130 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -7,7 +7,7 @@ import io.ebean.core.type.DataReader; import io.ebean.core.type.ScalarType; import io.ebean.text.TextException; import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; -import io.ebeaninternal.server.util.Md5; +import io.ebeaninternal.server.util.Checksum; import javax.persistence.PersistenceException; import java.sql.SQLException; @@ -66,10 +66,14 @@ public class BeanPropertyJsonMapper extends BeanProperty { private static class Md5MutableHash implements MutableHash { - private final String md5; + private final String hash; Md5MutableHash(String json) { - md5 = Md5.hash(json); + this.hash = hash(json); + } + + private String hash(String json) { + return String.valueOf(Checksum.checksum(json)); } @Override @@ -79,7 +83,7 @@ public class BeanPropertyJsonMapper extends BeanProperty { @Override public boolean isEqualToJson(String json) { - return Md5.hash(json).equals(md5); + return hash(json).equals(hash); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java new file mode 100644 index 000000000..87ee6e7e8 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java @@ -0,0 +1,20 @@ +package io.ebeaninternal.server.util; + +import java.nio.charset.StandardCharsets; +import java.util.zip.Adler32; + +/** + * Compute a checksum for String content. Use when we desire cheaper option than MD5. + */ +public final class Checksum { + + /** + * Return the checksum for the given String input. + */ + public static long checksum(String input) { + Adler32 adler32 = new Adler32(); + final byte[] bytes = input.getBytes(StandardCharsets.UTF_8); + adler32.update(bytes, 0, bytes.length); + return adler32.getValue(); + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java index 1c848f55d..7329d3f25 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java @@ -21,7 +21,6 @@ public final class Md5 { * Convert the digest into a hex value. */ private static String digestToHex(byte[] digest) { - StringBuilder sb = new StringBuilder(); for (byte aDigest : digest) { sb.append(Integer.toString((aDigest & 0xff) + 0x100, 16).substring(1)); diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java new file mode 100644 index 000000000..58342df80 --- /dev/null +++ b/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java @@ -0,0 +1,18 @@ +package io.ebeaninternal.server.util; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ChecksumTest { + + @Test + public void checksum() { + + final long val = Checksum.checksum("Hello world"); + assertThat(val).isEqualTo(413860925L); + + assertThat(Checksum.checksum("Hello world")).isEqualTo(val); + assertThat(Checksum.checksum("hello world")).isNotEqualTo(val); + } +}