From aed18543882d1cc6a7d18bce59a6a1ac2156ca9c Mon Sep 17 00:00:00 2001 From: Him188moe Date: Thu, 22 Aug 2019 00:05:57 +0800 Subject: [PATCH] update --- .../java/net/mamoe/mirai/network/Robot.kt | 22 +++++++------ .../network/packet/client/ClientPacket.kt | 2 +- .../packet/client/login/ClientLoginPacket.kt | 31 ++++++++++--------- .../network/packet/server/ServerPacket.kt | 11 +++++-- .../login/ServerLoginResponseResendPacket.kt | 4 +-- .../login/ServerLoginResponseSuccessPacket.kt | 27 ++++++++++------ .../server/touch/ServerTouchResponsePacket.kt | 4 +-- .../main/java/net/mamoe/mirai/util/Utils.kt | 2 +- mirai-core/src/test/java/HexComparator.java | 6 ++-- 9 files changed, 65 insertions(+), 44 deletions(-) diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/Robot.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/Robot.kt index 6dc906ace..8161f9b44 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/Robot.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/Robot.kt @@ -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()) } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientPacket.kt index 9fdbad856..5560aa59e 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientPacket.kt @@ -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) diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/login/ClientLoginPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/login/ClientLoginPacket.kt index 7a4354c82..47b706864 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/login/ClientLoginPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/login/ClientLoginPacket.kt @@ -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 - this.writeTLV0006(qq, password, loginTime, loginIP, tgtgtKey) + 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 diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt index f695112e4..59f8c1d90 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt @@ -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) } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseResendPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseResendPacket.kt index 36a06ddda..1a336c2ae 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseResendPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseResendPacket.kt @@ -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 -> { diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseSuccessPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseSuccessPacket.kt index 376d44588..314217f56 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseSuccessPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseSuccessPacket.kt @@ -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 @@ -39,11 +42,11 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream, val packetDataLen //?? var b = this.input.readNBytes(2) val msgLength = when (b.toUByteArray().toHexString()) { - "01 07" -> 0 - "00 33" -> 28 - "01 10" -> 65 - else -> throw IllegalStateException() - }//144 + "01 07" -> 0 + "00 33" -> 28 + "01 10" -> 65 + else -> throw IllegalStateException() + }//144 System.out.println(msgLength) @@ -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) } } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/touch/ServerTouchResponsePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/touch/ServerTouchResponsePacket.kt index ea78ab557..88d4eecfc 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/touch/ServerTouchResponsePacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/touch/ServerTouchResponsePacket.kt @@ -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() diff --git a/mirai-core/src/main/java/net/mamoe/mirai/util/Utils.kt b/mirai-core/src/main/java/net/mamoe/mirai/util/Utils.kt index 749044dea..6007a611a 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/util/Utils.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/util/Utils.kt @@ -67,7 +67,7 @@ fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDat @ExperimentalUnsignedTypes fun getRandomKey(length: Int): ByteArray { val bytes = LinkedList(); - for (i in 0..length) bytes.add((Math.random() * 255).toByte()) + repeat(length) { bytes.add((Math.random() * 255).toByte()) } return bytes.toByteArray(); } diff --git a/mirai-core/src/test/java/HexComparator.java b/mirai-core/src/test/java/HexComparator.java index bc042a717..3520a2a03 100644 --- a/mirai-core/src/test/java/HexComparator.java +++ b/mirai-core/src/test/java/HexComparator.java @@ -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(