ByteArray.kt 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package com.example.whatever.extentions
  2. import android.util.Base64
  3. import com.example.whatever.util.CRC16
  4. import java.io.ByteArrayOutputStream
  5. import kotlin.experimental.xor
  6. fun ByteArray.startsWith(prefix: ByteArray): Boolean {
  7. require(this.size >= prefix.size) { "ByteArray is smaller than the prefix." }
  8. for (i in prefix.indices) {
  9. if (this[i] != prefix[i]) {
  10. return false
  11. }
  12. }
  13. return true
  14. }
  15. fun ByteArray.base64() : String {
  16. return Base64.encodeToString(this, Base64.NO_WRAP)
  17. }
  18. private val hexEncodingTable = byteArrayOf(
  19. '0'.toByte(), '1'.toByte(), '2'.toByte(), '3'.toByte(), '4'.toByte(), '5'.toByte(), '6'.toByte(), '7'.toByte(),
  20. '8'.toByte(), '9'.toByte(), 'A'.toByte(), 'B'.toByte(), 'C'.toByte(), 'D'.toByte(), 'E'.toByte(), 'F'.toByte()
  21. )
  22. fun ByteArray.toHexStrings(space: Boolean = true) : String {
  23. val out = ByteArrayOutputStream()
  24. try {
  25. for (i in 0 until size) {
  26. val v: Int = this[i].toInt() and 0xff
  27. out.write(hexEncodingTable[v ushr 4].toInt())
  28. out.write(hexEncodingTable[v and 0xf].toInt())
  29. if (space) {
  30. out.write(' '.toInt())
  31. }
  32. }
  33. } catch (e: java.lang.Exception) {
  34. throw IllegalStateException("exception encoding Hex string: " + e.message, e)
  35. }
  36. val bytes = out.toByteArray()
  37. return String(bytes)
  38. }
  39. const val RADIX_62 = 62
  40. /**
  41. * 把[from, to) 部分的子数组,转换为以 0-9 a-z A-Z 共 62个字符组成的数字
  42. *
  43. * @param from 起始
  44. * @param to 结束(不包含)
  45. */
  46. fun ByteArray.to62Num(from: Int, to: Int) : Int {
  47. var sum = 0
  48. var scale = 1
  49. for (i in to - 1 downTo from) {
  50. sum += from62(this[i]) * scale
  51. scale *= RADIX_62
  52. }
  53. return sum
  54. }
  55. /**
  56. * 把[from, to) 部分的字节做异或
  57. */
  58. fun ByteArray.xor(from: Int, to: Int) : Byte {
  59. var res = this[from]
  60. for (i in (from + 1) until to) {
  61. res = res xor this[i]
  62. }
  63. return res
  64. }
  65. private fun from62(b: Byte): Int {
  66. if (b in 0x30..0x39) {
  67. return b - 0x30
  68. }
  69. if (b in 0x61..0x7a) {
  70. return b - 0x57
  71. }
  72. if (b in 0x41..0x5a) {
  73. return b - 0x1d
  74. }
  75. throw IllegalArgumentException("$b is not a num char")
  76. }
  77. /**
  78. * 计算 [from, to) 部分的字节做 的 CRC16 校验值
  79. * @return 两字节的校验值
  80. */
  81. fun ByteArray.crc16(from: Int = 0, to: Int = size) : ByteArray {
  82. val value = CRC16.crc16(this, from.coerceAtLeast(0), to.coerceAtMost(size))
  83. val c1 = (0xff00 and value shr 8).toByte()
  84. val c2 = (0xff and value).toByte()
  85. return byteArrayOf(c1, c2)
  86. }