يمكنني بناء BigInt مع أي صفيف بايت (سكالا)?
-
10-07-2019 - |
سؤال
أنا أحاول أن تمثل نتيجة تجزئة MD5 في أقصر وقت ممكن السلسلة.يبدو مضيعة للوقت فقط تحويله الى hex string وترك ز ي تذهب سدى.
فكرة واحدة كان هو الحصول على تجزئة MD5 من المدخلات كما صفيف من البايت و بناء BigInt
مع ذلك.ومن ثم يمكنني الاتصال toString(36)
, و الحصول على عدد كقاعدة-36 في سلسلة (-?[0-9a-z]*
, عدد يمكن أن تكون إيجابية أو سلبية).يعمل بالنسبة لي.
المشكلة أنني لست متأكدا من أن BigInt
يمكن بناؤها مع أي مجموعة من بايت, و لا أستطيع إثبات ذلك مع اختبار (على الأقل ليس في الوقت المناسب!).أعتقد ذلك لأنني أفهم أن BigInt يمكن من حجم التعسفي.أنا لا يمكن استخدام هذا الأسلوب حتى أنا متأكد من أنه سوف يعمل على جميع النواتج الممكنة.لذا يمكن لأحد أن يقول لي ما إذا كان سيتم عمل لجميع المدخلات (أو كيف يمكن بسهولة تحويل صفيف بايت لذلك يمكن أن تكون ممثلة في قاعدة 36).
التوضيح:يجب تنفيذ, أنا أسأل عن سلوك على كامل المجال (أي00000000000000000000000000000000 إلى FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
المحلول
بناء على ملاحظاتك أعلاه ، بعد تنفيذ موثوق بها ترميز/فك التعسفي صفيف بايت:
package blevins.example
object BigIntEncoder {
val radix = 36
implicit def byteArrayToString(ba: Array[Byte]): String = {
new java.math.BigInteger(addByte(ba)).toString(radix)
}
implicit def stringToByteArray(s: String): Array[Byte] = {
stripByte(new java.math.BigInteger(s, radix).toByteArray)
}
def addByte(ba: Array[Byte]): Array[Byte] = {
val h = new Array[Byte](1)
h(0) = 0x01
h ++ ba
}
def stripByte(ba: Array[Byte]): Array[Byte] = {
ba.slice(1,ba.size)
}
}
ملاحظة أننا مضيفا إضافية 0x01 بايت إلى رئيس مجموعة لتجنب أي آثار جانبية من تناول اثنين تكمل صفيف بايت.
تحرير:اختبار المعنية لإثبات هذا هو توثيقها هنا: http://cleverlytitled.blogspot.com/2009/10/scalacheck.html
نصائح أخرى
لن ترميز Base64 تكون أقصر من Base36?يمكنك العثور على الكثير من التطبيقات في جميع أنحاء.
ولكن في الواقع الإجابة على السؤال:
// Make a big randomly-filled byte array
val random = scala.util.Random
val arraySize = 8543
val bytes: Array[Byte] = new Array[Byte](arraySize) // make some big array
random.nextBytes(bytes) // fill it randomly
// Make a BigInt out of it and the corresponding base36 string representation
val bi: BigInt = new BigInt(new java.math.BigInteger(bytes))
val strRep: String = bi.toString(36)
// Make a new BigInt out of the string rep. Does it match?
val bi2: BigInt = new BigInt(new java.math.BigInteger(strRep, 36))
if (bi == bi2) {
println("yippee!!")
}
// Make a new byte array out of the BigInt. Does it match the original array?
val bytes2: Array[Byte] = bi2.toByteArray
if (bytes deepEquals bytes2) {
println("yippee again!!")
}