BigInteger auf 128Bit kürzen

miasma

Aktives Mitglied
Hallo,

ich hab eine recht blöde Frage nehm ich an, aber wie konvertiert man am besten ein BigInteger bzw. kürzt den auf 128Bit (basierend auf einem SHA256 konvertiert in BigInteger und ein paar Berechnungen damit für einen rolling hash)? In meinem Fall sollte das super schnell sein, da es etliche Millionen mal aufgerufen wird und momentan laut Profiler ne ganze Menge CPU-Zeit schluckt durch den Modulo Operator:

hash.mod(MAX_POSITIVE_VALUE_128_BIT)

wie nehm ich denn da am besten einfach die ersten 128 Bit oder sowas?

Beste Grüße
Johannes
 
Was genau willst du denn machen?

Die interne Representierung von einem BigDecimal ist nicht "einfach nur" eine lange Byte-Kette, soweit ich weisz, die ist etwas komplexer. Wenn du einen BigDecimal auf einen bestimmten Wertebereich einpassen willst, dann wäre max/min/mod schon die richtige Wahl. Du kannst einen BigDecimal auch direkt in einen BigInteger wandeln.
 
Ich will eigentlich lediglich einen BigInteger von möglicherwiese 256 Bits auf die ersten 128 Bits kürzen (möglicherweise sinds auch mehr als 256 Bits, aber sollte ja egal sein).

Letztendlich geht es mir vor allem darum Speicherplatz zu sparen, einmal in-memory in einem transaction-log und einmal, wenns dauerhaft auf dem flash drive/SSD oder HDD liegt. Zumindest scheint bisher ja die Annahme zu sein, dass auch die ersten 128 Bits von einem SHA256 hash genügen um möglichst kollisionsfrei zu sein usw..
 
Eventuell sowas?

Java:
static BigInteger to128BitsAtMaximumBigInteger(BigInteger hash) {
  final var bytes = hash.toByteArray();
  final var newBytes = new byte[16];
  System.arraycopy(bytes, 0, newBytes, 0, Math.min(bytes.length, 16));
  hash = null;
  return new BigInteger(newBytes);
}
 
Ah, sorry, hatte die ganze Zeit BigDecimal gelesen. Bei einem BigInteger kannst du toByteArray aufrufen, und dann damit machen was du willst. Aber meiner Meinung nach ist ein BigInteger nicht geeignet um eine Hash-Summe abzubilden beziehungsweise darzustellen. Da waere es besser wenn du die Hash-Summe als byte-Array hast und dann darin irgendwas kuerzt.
 
// 2^128-1.
BigInteger MAX_POSITIVE_VALUE_128_BIT = new BigInteger("340282366920938463463374607431768211455");

Meine obige Methode scheint allerdings sogar langsamer als ein BigInteger.mod(MAX_POSITIVE_VALUE_128_BIT). Wird halt recht häufig aufgerufen und scheint neben dem Hashen selbst natürlich auch recht CPU-intensiv zu sein. Dachte ich könnte da noch was optimieren, aber wenn die neue BigInteger-Instanz mit den ersten 16 bytes erzeugen langsamer ist, weiß ich auch nicht ;-) hab jetzt aber keinen JMH-Benchmark dafür geschrieben.
 

Anhänge

  • Screenshot from 2022-08-04 11-38-36.png
    Screenshot from 2022-08-04 11-38-36.png
    77,8 KB · Aufrufe: 2

Zurück
Oben