forked from sergeych/crypto2
100 lines
2.7 KiB
Kotlin
100 lines
2.7 KiB
Kotlin
/*
|
|
* Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
|
|
*
|
|
* You may use, distribute and modify this code under the
|
|
* terms of the private license, which you must obtain from the author
|
|
*
|
|
* To obtain the license, contact the author: https://t.me/real_sergeych or email to
|
|
* real dot sergeych at gmail.
|
|
*/
|
|
|
|
package net.sergeych.crypto2
|
|
|
|
import kotlinx.serialization.Serializable
|
|
import net.sergeych.bintools.decodeHex
|
|
import net.sergeych.bintools.encodeToHex
|
|
import kotlin.math.min
|
|
|
|
/**
|
|
* Bytes sequence with comparison, concatenation, and string representation,
|
|
* could be used as hash keys for pure binary values, etc.
|
|
*/
|
|
@Suppress("unused")
|
|
@Serializable
|
|
class ByteChunk(val data: UByteArray): Comparable<ByteChunk> {
|
|
|
|
val size: Int get() = data.size
|
|
|
|
/**
|
|
* Per-byte comparison also of different length. From two chunks
|
|
* of different size but equal beginning, the shorter is considered
|
|
* the smaller.
|
|
*/
|
|
override fun compareTo(other: ByteChunk): Int {
|
|
val limit = min(size, other.size)
|
|
for( i in 0 ..< limit) {
|
|
val own = data[i]
|
|
val their = other.data[i]
|
|
if( own < their) return -1
|
|
else if( own > their) return 1
|
|
}
|
|
if( size < other.size ) return -1
|
|
if( size > other.size ) return 1
|
|
return 0
|
|
}
|
|
|
|
/**
|
|
* Equal chunks means content equality.
|
|
*/
|
|
override fun equals(other: Any?): Boolean {
|
|
if (this === other) return true
|
|
if (other !is ByteChunk) return false
|
|
|
|
return data contentEquals other.data
|
|
}
|
|
|
|
/**
|
|
* Content-based hash code
|
|
*/
|
|
override fun hashCode(): Int {
|
|
return data.contentHashCode()
|
|
}
|
|
|
|
/**
|
|
* hex representation of data
|
|
*/
|
|
override fun toString(): String = base64Url
|
|
|
|
/**
|
|
* Hex encoded data
|
|
*/
|
|
val hex by lazy { data.encodeToHex() }
|
|
|
|
val base64Url by lazy { data.encodeToBase64Url() }
|
|
|
|
/**
|
|
* human-readable dump
|
|
*/
|
|
val dump by lazy { data.toDump() }
|
|
|
|
/**
|
|
* Concatenate two chunks and return new one
|
|
*/
|
|
operator fun plus(other: ByteChunk): ByteChunk = ByteChunk(data + other.data)
|
|
|
|
fun toByteArray(): ByteArray = data.asByteArray()
|
|
fun toUByteArray(): UByteArray = data
|
|
|
|
companion object {
|
|
fun fromHex(hex: String): ByteChunk = ByteChunk(hex.decodeHex().asUByteArray())
|
|
fun random(sizeInBytes: Int=16) = randomUBytes(sizeInBytes).toChunk()
|
|
}
|
|
}
|
|
|
|
private fun UByteArray.toChunk(): ByteChunk = ByteChunk(this)
|
|
@Suppress("unused")
|
|
private fun ByteArray.toChunk(): ByteChunk = ByteChunk(this.asUByteArray())
|
|
|
|
@Suppress("unused")
|
|
fun ByteArray.asChunk() = ByteChunk(toUByteArray())
|
|
fun UByteArray.asChunk(): ByteChunk = ByteChunk(this) |