Create custom base64 encoding system
This commit is contained in:
parent
9eca6d1910
commit
3f99420006
54
src/main/kotlin/Base64.kt
Normal file
54
src/main/kotlin/Base64.kt
Normal file
@ -0,0 +1,54 @@
|
||||
import kotlin.math.min
|
||||
|
||||
private val base64 = charArrayOf(
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
)
|
||||
internal fun b64Encode(src: ByteArray, off: Int, end: Int, dst: ByteArray): Int {
|
||||
var sp = off
|
||||
val slen = (end - off) / 3 * 3
|
||||
val sl = off + slen
|
||||
var dp = 0
|
||||
while (sp < sl) {
|
||||
val sl0 = min(sp + slen, sl)
|
||||
|
||||
var sp0 = sp
|
||||
var dp0 = dp
|
||||
while (sp0 < sl0) {
|
||||
val bits: Int = src[sp0++].toInt() and 0xff shl 16 or (
|
||||
src[sp0++].toInt() and 0xff shl 8) or
|
||||
(src[sp0++].toInt() and 0xff)
|
||||
dst[dp0++] = base64[bits ushr 18 and 0x3f].code.toByte()
|
||||
dst[dp0++] = base64[bits ushr 12 and 0x3f].code.toByte()
|
||||
dst[dp0++] = base64[bits ushr 6 and 0x3f].code.toByte()
|
||||
dst[dp0++] = base64[bits and 0x3f].code.toByte()
|
||||
}
|
||||
|
||||
val dlen = (sl0 - sp) / 3 * 4
|
||||
dp += dlen
|
||||
sp = sl0
|
||||
}
|
||||
if (sp < end) { // 1 or 2 leftover bytes
|
||||
val b0: Int = src[sp++].toInt() and 0xff
|
||||
dst[dp++] = base64[b0 shr 2].code.toByte()
|
||||
if (sp == end) {
|
||||
dst[dp++] = base64[b0 shl 4 and 0x3f].code.toByte()
|
||||
} else {
|
||||
val b1: Int = src[sp].toInt() and 0xff
|
||||
dst[dp++] = base64[b0 shl 4 and 0x3f or (b1 shr 4)].code.toByte()
|
||||
dst[dp++] = base64[b1 shl 2 and 0x3f].code.toByte()
|
||||
}
|
||||
}
|
||||
return dp
|
||||
}
|
||||
|
||||
internal fun b64OutLen(srclen: Int, throwOOME: Boolean) =
|
||||
try {
|
||||
val n = srclen % 3
|
||||
Math.addExact(Math.multiplyExact(4, srclen / 3), if (n == 0) 0 else n + 1)
|
||||
} catch (ex: ArithmeticException) {
|
||||
if (throwOOME) throw OutOfMemoryError("Encoded size is too large") else -1
|
||||
}
|
@ -4,8 +4,6 @@ import org.bukkit.World
|
||||
import org.bukkit.entity.Player
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.*
|
||||
import kotlin.Comparator
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.experimental.and
|
||||
import kotlin.experimental.inv
|
||||
import kotlin.experimental.or
|
||||
@ -18,24 +16,6 @@ val PORTAL_COMPARATOR = Comparator<Portal> { a, b -> a.compareByOrder(b, { world
|
||||
private val threadLocalInputBuffer = ThreadLocal.withInitial { ReallocatingBuffer(ByteBuffer.allocate(96)) }
|
||||
private val threadLocalOutputBuffer = ThreadLocal.withInitial { ReallocatingBuffer(ByteBuffer.allocate(96)) }
|
||||
|
||||
private val method_encode0 = run {
|
||||
val method = Base64::class.java.getDeclaredMethod(
|
||||
"encode0",
|
||||
ByteArray::class.java,
|
||||
Int::class.java,
|
||||
Int::class.java,
|
||||
ByteArray::class.java
|
||||
)
|
||||
method.isAccessible = true
|
||||
return@run method
|
||||
}
|
||||
|
||||
private val method_encodedOutLength = run {
|
||||
val method = Base64::class.java.getDeclaredMethod("encodedOutLength", Int::class.java, Boolean::class.java)
|
||||
method.isAccessible = true
|
||||
return@run method
|
||||
}
|
||||
|
||||
enum class PortalResult {
|
||||
NO_LINK,
|
||||
DISALLOWED,
|
||||
@ -169,10 +149,9 @@ class Portal(
|
||||
|
||||
val outputBuffer = threadLocalOutputBuffer.get()
|
||||
outputBuffer.position = 0
|
||||
val encoder = Base64.getEncoder().withoutPadding()
|
||||
|
||||
outputBuffer.ensureAtLeast(method_encodedOutLength.invoke(encoder, buffer.position, true) as Int)
|
||||
val len = method_encode0.invoke(encoder, buffer.buffer.array(), 0, outputBuffer.buffer.array()) as Int
|
||||
outputBuffer.ensureAtLeast(b64OutLen(buffer.position, true))
|
||||
val len = b64Encode(buffer.buffer.array(), 0, buffer.position, outputBuffer.buffer.array())
|
||||
|
||||
|
||||
return buffer.position.toString(16).padStart(8, '0') + String(outputBuffer.buffer.array(), 0, len)
|
||||
|
Loading…
x
Reference in New Issue
Block a user