This commit is contained in:
Him188moe 2019-08-22 00:05:57 +08:00
parent 61138e8cee
commit aed1854388
9 changed files with 65 additions and 44 deletions

View File

@ -1,8 +1,6 @@
package net.mamoe.mirai.network
import io.netty.channel.Channel
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.client.login.*
import net.mamoe.mirai.network.packet.client.writeHex
@ -70,9 +68,9 @@ class Robot(val number: Int, private val password: String) {
} else {//password submission
this.loginIP = packet.loginIP
this.loginTime = packet.loginTime
this.token0825 = packet.token
this.token0825 = packet.token0825
this.tgtgtKey = packet.tgtgtKey
sendPacket(ClientPasswordSubmissionPacket(this.number, this.password, packet.loginTime, packet.loginIP, packet.tgtgtKey, packet.token))
sendPacket(ClientPasswordSubmissionPacket(this.number, this.password, packet.loginTime, packet.loginIP, packet.tgtgtKey, packet.token0825))
}
}
@ -83,7 +81,7 @@ class Robot(val number: Int, private val password: String) {
}
is ServerLoginResponseVerificationCodePacket -> {
//[token00BA]可能来自这里
//[token00BA]来源之一: 验证码
this.token00BA = packet.token00BA
if (packet.unknownBoolean != null && packet.unknownBoolean!!) {
this.sequence = 1
@ -97,13 +95,17 @@ class Robot(val number: Int, private val password: String) {
sendPacket(ClientLoginSucceedConfirmationPacket(this.number, this.serverIP, this.loginIP, this.md5_32, packet.token38, packet.token88, packet.encryptionKey, this.tlv0105))
}
//这个有可能是客户端发送验证码之后收到的回复验证码是否正确?
//是ClientPasswordSubmissionPacket之后服务器回复的
is ServerLoginResponseResendPacket -> {
if (packet.token00BA != null) {
this.token00BA = packet.token00BA!!
println(token00BA)
}
if (packet.flag == ServerLoginResponseResendPacket.Flag.`08 36 31 03`) {
this.tgtgtKey = packet.tgtgtKey
sendPacket(ClientLoginResendPacket3104(this.number, this.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA))
sendPacket(ClientLoginResendPacket3104(this.number, this.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA, packet._0836_tlv0006_encr))
} else {
sendPacket(ClientLoginResendPacket3106(this.number, this.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA))
sendPacket(ClientLoginResendPacket3106(this.number, this.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA, packet._0836_tlv0006_encr))
}
}
@ -135,9 +137,9 @@ class Robot(val number: Int, private val password: String) {
p.socketAddress = this.serverAddress*/
//ctx.writeAndFlush(packet.toByteArray()).sync()
MiraiLogger info "Sending: $packet"
GlobalScope.launch {
//GlobalScope.launch {
send(packet.toByteArray())
}
//}
//println(channel!!.writeAndFlush(packet.toByteArray()).channel().connect(serverAddress).sync().get())
}

View File

@ -131,7 +131,7 @@ fun DataOutputStream.writeTLV0006(qq: Int, password: String, loginTime: Int, log
println(md5_1.toUByteArray().toHexString())
println(md5_2.toUByteArray().toHexString())
it.write(md5_1)
it.writeShort(loginTime)
it.writeInt(loginTime)
it.writeByte(0);
it.writeZero(4 * 3)
it.writeIP(loginIP)

View File

@ -3,10 +3,8 @@ package net.mamoe.mirai.network.packet.client.login
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.*
import net.mamoe.mirai.util.ByteArrayDataOutputStream
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.getRandomKey
import net.mamoe.mirai.util.hexToBytes
import net.mamoe.mirai.util.*
import java.io.DataOutputStream
import java.net.InetAddress
/**
@ -33,22 +31,23 @@ class ClientPasswordSubmissionPacket(
this.writeHex(Protocol._0836key1)
this.encryptAndWrite(Protocol.shareKey.hexToBytes()) {
writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825)
writePart2()
it.writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825)
it.writePart2()
println(it.toByteArray().toUHexString())
}
}
}
@PacketId("08 36 31 04")
@ExperimentalUnsignedTypes
class ClientLoginResendPacket3104(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray) : ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA)
class ClientLoginResendPacket3104(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray, tlv_0006_encr: ByteArray? = null) : ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA, tlv_0006_encr)
@PacketId("08 36 31 06")
@ExperimentalUnsignedTypes
class ClientLoginResendPacket3106(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray) : ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA)
class ClientLoginResendPacket3106(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray, tlv_0006_encr: ByteArray? = null) : ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA, tlv_0006_encr)
@ExperimentalUnsignedTypes
open class ClientLoginResendPacket internal constructor(val qq: Int, val password: String, val loginTime: Int, val loginIP: String, val tgtgtKey: ByteArray, val token0825: ByteArray, val token00BA: ByteArray) : ClientPacket() {
open class ClientLoginResendPacket internal constructor(val qq: Int, val password: String, val loginTime: Int, val loginIP: String, val tgtgtKey: ByteArray, val token0825: ByteArray, val token00BA: ByteArray, val tlv_0006_encr: ByteArray? = null) : ClientPacket() {
override fun encode() {
this.writeQQ(qq)
this.writeHex(Protocol._0836_622_fix1)
@ -58,7 +57,7 @@ open class ClientLoginResendPacket internal constructor(val qq: Int, val passwor
this.write(TEACryptor.encrypt(object : ByteArrayDataOutputStream() {
override fun toByteArray(): ByteArray {
writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825)
writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825, tlv_0006_encr)
this.writeHex("01 10") //tag
this.writeHex("00 3C")//length
@ -133,9 +132,9 @@ class ClientLoginSucceedConfirmationPacket(
* @author Him188moe
*/
@ExperimentalUnsignedTypes
private fun ClientPacket.writePart1(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray) {
private fun DataOutputStream.writePart1(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, tlv_0006_encr: ByteArray? = null) {
this.writeInt(System.currentTimeMillis().toInt())
//this.writeInt(System.currentTimeMillis().toInt())
this.writeHex("01 12")//tag
this.writeHex("00 38")//length
this.write(token0825)//length
@ -149,7 +148,11 @@ private fun ClientPacket.writePart1(qq: Int, password: String, loginTime: Int, l
this.writeQQ(qq)
this.writeHex("00 06")//tag
this.writeHex("00 78")//length
if (tlv_0006_encr != null) {
this.write(tlv_0006_encr)
} else {
this.writeTLV0006(qq, password, loginTime, loginIP, tgtgtKey)
}
//fix
this.writeHex(Protocol._0836_622_fix2)
this.writeHex("00 1A")//tag
@ -169,7 +172,7 @@ private fun ClientPacket.writePart1(qq: Int, password: String, loginTime: Int, l
}
@ExperimentalUnsignedTypes
private fun ClientPacket.writePart2() {
private fun DataOutputStream.writePart2() {
this.writeHex("03 12")//tag
this.writeHex("00 05")//length

View File

@ -32,7 +32,9 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
when (bytes.size) {
271, 207 -> return ServerLoginResponseResendPacketEncrypted(stream, when (idBytes) {
"08 36 31 03" -> ServerLoginResponseResendPacket.Flag.`08 36 31 03`
else -> ServerLoginResponseResendPacket.Flag.OTHER
else -> {
println("flag=$idBytes"); ServerLoginResponseResendPacket.Flag.OTHER
}
})
871 -> return ServerLoginResponseVerificationCodePacket(stream, bytes.size)
}
@ -48,7 +50,12 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
263 -> ServerLoginResponseFailedPacket.State.UNKNOWN_QQ_NUMBER
551, 487 -> ServerLoginResponseFailedPacket.State.DEVICE_LOCK
359 -> ServerLoginResponseFailedPacket.State.TAKEN_BACK
else -> throw IllegalStateException()
//unknown
63 -> throw IllegalArgumentException(bytes.size.toString())
351 -> throw IllegalArgumentException(bytes.size.toString())
else -> throw IllegalArgumentException(bytes.size.toString())
}, stream)
}

View File

@ -18,7 +18,7 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) :
}
lateinit var _0836_tlv0006_encr: ByteArray;
lateinit var token: ByteArray
var token00BA: ByteArray? = null
lateinit var tgtgtKey: ByteArray
override fun decode() {
@ -29,7 +29,7 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) :
when (flag) {
Flag.`08 36 31 03` -> {
token = this.input.goto(153).readNBytes(56)
token00BA = this.input.goto(153).readNBytes(56)
}
Flag.OTHER -> {

View File

@ -1,7 +1,10 @@
package net.mamoe.mirai.network.packet.server.login
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.server.*
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.goto
import net.mamoe.mirai.network.packet.server.readNBytes
import net.mamoe.mirai.network.packet.server.readVarString
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.hexToBytes
import net.mamoe.mirai.util.toHexString
@ -103,9 +106,9 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream, val packetDataLen
else -> throw IllegalStateException()
}
this._0828_rec_decr_key = this.input.readNBytes(171 + msgLength,16)
this._0828_rec_decr_key = this.input.readNBytes(171 + msgLength, 16)
this.token88 = this.input.readNBytes(189 + msgLength,136)
this.token88 = this.input.readNBytes(189 + msgLength, 136)
val nickLength = this.input.goto(624 + msgLength).readByte().toInt()
this.nick = this.input.readVarString(nickLength)
@ -123,8 +126,12 @@ class ServerLoginResponseSuccessPacketEncrypted(input: DataInputStream, val leng
@ExperimentalUnsignedTypes
fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseSuccessPacket {//todo test
this.input.skip(7)
return ServerLoginResponseSuccessPacket(TEACryptor.decrypt(TEACryptor.decrypt(this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, Protocol.shareKey.hexToBytes()), tgtgtKey).dataInputStream(), length);
input.skip(7)
var bytes = input.readAllBytes();
bytes = bytes.copyOfRange(0, bytes.size - 1);
println(bytes.toUByteArray().toHexString())
return ServerLoginResponseSuccessPacket(DataInputStream(TEACryptor.decrypt(bytes, Protocol.shareKey.hexToBytes()).inputStream()), length);
//TeaDecrypt(取文本中间(data, 43, 取文本长度(data) 45), m_0828_rec_decr_key)
}
}

View File

@ -22,7 +22,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
var loginTime: Int = 0
lateinit var loginIP: String
lateinit var token: ByteArray
lateinit var token0825: ByteArray
lateinit var tgtgtKey: ByteArray
enum class Type {
@ -39,7 +39,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
}
0x00 -> {
input.skip(4)
token = input.readNBytes(56)
token0825 = input.readNBytes(56)
input.skip(6)
loginTime = input.readInt()

View File

@ -67,7 +67,7 @@ fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDat
@ExperimentalUnsignedTypes
fun getRandomKey(length: Int): ByteArray {
val bytes = LinkedList<Byte>();
for (i in 0..length) bytes.add((Math.random() * 255).toByte())
repeat(length) { bytes.add((Math.random() * 255).toByte()) }
return bytes.toByteArray();
}

View File

@ -172,9 +172,11 @@ public class HexComparator {
public static void main(String[] args) {
System.out.println(HexComparator.compare(
"02 37 13 08 36 31 03 76 E4 B8 DD 03 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 01 01 03 00 19 02 6D 28 41 D2 A5 6F D2 FC 3E 2A 1F 03 75 DE 6E 28 8F A8 19 3E 5F 16 49 D3 00 00 00 10 EF 4A 36 6A 16 A8 E6 3D 2E EA BD 1F 98 C1 3C DA B4 AF 5C C0 01 12 00 38 9B 7C 43 9E FE 4D E8 AB BD A0 25 92 F6 F5 62 F4 9E D6 98 96 87 95 C0 96 47 B7 13 F5 B8 A1 13 46 FE 50 A3 8A 2C 65 95 D5 EF 1F F2 93 95 66 BA 92 39 49 1B 3C BB D5 6F AB 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 5C BB 33 F1 0A 1C BF DF CD 74 CB 03 0B E6 5D 5C 9B EC 02 3D 0D 1E 68 1F 24 82 4C C8 E4 15 38 58 46 23 C8 3F 95 50 4E 15 4B B2 A1 E2 E4 C2 59 A2 59 5A 9F 11 EF 3D 7F 41 D9 01 CB 48 61 37 6D E0 67 AB B8 29 29 43 D8 3E E1 2E E3 58 FB 0D AA DE 8D D8 F1 47 51 29 C7 CE 91 97 4D 1A B6 F7 F5 4D DA 0A 63 9F 81 4D 68 E2 C8 CE 22 2A E7 3A 50 41 92 A1 11 18 DB 9A 82 78 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 1A B3 88 3C 6E 39 D0 88 49 AC 2C 89 8E C6 CF 1D 56 BB 01 54 62 5F 87 40 B3 6C E0 E3 84 7C FD 15 1D E0 B6 39 A5 8E 9F FF 36 40 F1 E8 26 0E EB 39 03 C9 0F A2 D7 BD FA 67 91 82 E8 BE 74 2D 93 AF 00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 00 00 00 01 03 00 14 00 01 00 10 60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6 03 12 00 05 01 00 00 00 01 05 08 00 05 10 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 9E 12 A9 12 02 D7 77 E7 C1 61 10 F7 C5 AA F6 4E 12 CA BF D9 B2 33 05 C4 EF 23 E6 0B 90 23 7A FC EF 31 06 1A 3B 03\n\n"
//mirai
"01 12 00 38 4A 89 FA EE 24 BC B5 EC 6D DD A7 EE 9E 89 2C 00 4F BF 05 F3 98 46 5A 52 9E 8A 2A 14 96 ED F3 98 06 42 72 50 D0 5A CA 85 E1 68 2F 28 D3 84 0E 92 98 3E 3C 82 3F 59 5C A8 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 75 2A 22 99 DD A6 EE 95 9E 7F 11 F0 C7 93 FB E7 51 C5 72 22 FF DE 73 DC 5D 13 0E C0 7D 84 CF 18 4B 6B 10 E5 04 A4 40 79 45 6E 54 69 E5 8E FE 59 7A FF 68 E4 BB 5B 90 DE 07 1D A9 D6 64 5A 25 5E 2C 2F FB CF CA 37 57 05 F9 36 B5 58 BC E0 4D 1B 8A 7F A1 54 00 86 9C 30 47 C6 2E D1 42 E1 F8 4F 7F 5D 7E 80 BB EA 84 AF EA 98 47 9A F6 93 6D 35 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 19 B6 E2 4C 38 36 3F 8F E9 CD 18 54 93 F5 52 A7 2E 04 6C ED 58 39 92 5B 17 B6 F7 C0 45 07 49 0B A0 AF 35 E0 E2 49 98 29 B2 FB A7 7E D6 0F 96 BB FB FD C1 56 77 E0 3A 3E 32 E8 E7 CB 78 B2 9A D0 00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 00 00 00 01 03 00 14 00 01 00 10 60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6 03 12 00 05 01 00 00 00 01 05 08 00 05 10 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 79 FE 6A 47 E3 97 C4 5A 0D 38 BA CB 7F 47 47 D3 4F 63 30 53\n\n"
,
"02 37 13 08 36 31 03 76 E4 B8 DD 03 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 01 01 03 00 19 02 6D 28 41 D2 A5 6F D2 FC 3E 2A 1F 03 75 DE 6E 28 8F A8 19 3E 5F 16 49 D3 00 00 00 10 EF 4A 36 6A 16 A8 E6 3D 2E EA BD 1F 98 C1 3C DA EC CD 3D 2F 35 55 4C 8E B3 2C D9 55 E1 CE 71 DD 16 9C BB 24 E9 2C A6 98 77 A4 49 AB 2B EF 30 80 09 EB E3 04 4E AD D5 F4 E9 F3 55 54 D8 AC 9B F2 D6 78 25 F1 DF AF E2 7C 95 85 CB CF D6 FD 32 CE F5 4B 20 EA B8 D1 2D 77 69 75 40 6C 88 F0 6D 47 48 C6 5A 61 53 53 A3 58 A8 2E C2 F6 E2 44 E1 C2 8B 62 57 E2 8C 72 3C F7 5E EC 7E 48 BD 55 B4 83 38 0C D6 0A 1D 82 CA B5 CC 94 F8 53 E4 00 44 21 5E 26 39 1C EF 1E 5B 6C 94 F0 22 B9 FD 31 35 CF 8B B4 51 00 3A 0C FC 48 93 59 65 B6 C5 79 20 7B F3 3F 4F EA 1F 31 73 5F 93 0B 90 22 16 E1 02 30 DC 44 FC 87 D3 53 E4 E9 30 4A 92 E2 5B 6E EE 88 7B AC 03 17 67 89 DF 91 E4 9D 27 FF CA 04 D3 53 D9 39 52 47 63 F4 24 49 F1 1C 38 9F 01 6D DC AE 62 5A 37 7A 97 2B FA 0F AD DC 11 51 19 95 89 B9 9D DB C0 FD 3E 78 FF C0 1C 93 44 10 17 29 C1 7F F5 8B 31 E2 10 C4 F9 71 66 F5 05 D2 2A 9C EB 98 4D B7 71 5C F6 B6 7C 82 12 82 DF D6 40 0E C0 35 8F E7 22 D0 95 B4 27 42 DA CF CD 96 C1 06 6E 71 CD B7 A8 D5 0C 6D B1 09 F3 79 CB F6 DD 28 AF BC 0B 21 6F 82 37 B6 18 3D 88 CD 7E C6 FE 50 0D CE 3D 7E BB 5B B1 02 B0 B8 EE 90 59 C1 81 E8 D3 9C 6C ED C7 C5 45 F2 4B A3 40 A6 21 57 A0 0C 94 57 A3 7C 92 7C 6B 62 34 1A B1 AD EA 82 A0 55 E5 49 0D 08 E7 B3 B6 3D 0C 14 EF E9 D6 6D 0B C5 31 2B 07 23 41 1B 03 E6 5B B7 86 A7 7F 62 D8 ED 12 40 1B 8F 28 8F D1 FE 41 73 52 9D 25 08 94 B4 B6 6B B1 AB A4 50 87 9C 87 D2 1C C6 23 BD 28 50 6E 4C 20 2A 24 08 0C 08 E5 2E 7C 50 9C C8 34 D5 BD 81 D9 20 90 AB 4E FA 7F 5F B0 BB 18 54 33 65 CA 53 2E A0 6C 42 30 BD 8F EF E6 82 D9 21 1F C6 63 1C D3 57 D0 89 39 7C B7 71 EC DB 46 26 6E 5A F8 75 12 03 64 4C 94 D1 6B 7A 79 CE 28 8E 95 F4 00 CF 95 8A A0 DA 44 4A A5 5D 73 E5 F9 6C 83 2E E1 6E 03\n"
//e
"01 12 00 38 B5 E3 C5 4F F9 91 D1 10 B2 A0 CE 2B 5C C3 F3 6E 1F 0C 01 F5 89 13 50 A1 5F 9C C9 BD 58 09 C3 84 3D C0 1E EA 12 3F A3 F2 47 D0 77 19 8A 24 92 87 8B AD AD 16 97 7A 66 AD 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 4A AE 12 18 80 AC FE D3 7E 37 CA D8 9C 93 99 68 09 2B A8 FA B1 92 4A EB 8F 6E 69 EA F9 59 25 CA 39 90 69 A5 A7 15 73 97 52 9A B7 85 16 04 8E A8 CF 97 84 CD 13 67 A1 A9 C2 41 99 E7 74 96 C0 FC F9 5E 46 06 18 71 FF 85 7E EE 8A 62 05 90 F3 83 E2 97 10 5E 3C FE 70 F6 0B 92 2D B8 C7 A2 EE FE DD EE EF 8C 5E 86 EB D9 01 66 DB F1 31 DD 27 44 83 7F E4 5E 93 9C C6 05 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 EB E2 37 37 17 6D DB 96 38 C8 F3 67 12 50 80 9A C5 5E CB 8C 45 55 9F E4 7D 4F 4F F3 D2 8E BA AD 4A 0B F3 3B 99 B9 A5 CD 76 D7 4A 4B 69 9D 9F 21 36 A0 0F 94 CB 69 44 7A 87 39 27 23 F6 4A 66 D1 00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 00 00 00 01 03 00 14 00 01 00 10 60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6 03 12 00 05 01 00 00 00 01 05 08 00 05 01 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 12 C9 35 A8 26 70 AA 5A F7 F8 0B E6 6A FC 85 19 00 D4 CE EC "
));
System.out.println(HexComparator.compare(