classMK {Stream connection; TcpClient con; PublicMK (stringIP) {Con=NewTcpClient (); Con. Connect (IP,8728); Connection=(Stream) con. GetStream (); } Public voidClose () {connection. Close (); Con. Close (); } Public BOOLLogin (stringUsernamestringpassword) {Send ("/login",true); stringhash = Read () [0]. Split (New string[] {"ret="}, Stringsplitoptions.none) [1]; Send ("/login"); Send ("=name="+username); //The encrypted password is decrypted first (to ensure data security, the password is encrypted when the password is saved)//password= ...;Send ("=response=00"+ encodepassword (password, hash),true); if(Read () [0] =="!done") { return true; } Else { return false; } } Public voidSend (stringCoBOOLEndsentence=false) { byte[] Bajty =Encoding.UTF8.GetBytes (Co. ToCharArray ()); byte[] Velikost =Encodelength (bajty. Length); Connection. Write (Velikost,0, Velikost. Length); Connection. Write (Bajty,0, Bajty. Length); if(endsentence) {connection. WriteByte (0); } } Publiclist<string>Read () {List<string> output =Newlist<string>(); stringo =""; byte[] tmp =New byte[4]; Longcount; while(true) {tmp[3] = (byte) connection. ReadByte (); //if (tmp[3] = =) Tmp[3] = (byte) connection. ReadByte (); It sometimes happend to me//Mikrotik send some kind of "bonus" between words, this fixed things, not sure about it though if(tmp[3] ==0) {output. ADD (o); if(O.substring (0,5) =="!done") { Break; } Else{o=""; Continue; } } Else { if(tmp[3] <0x80) {Count= tmp[3]; } Else { if(tmp[3] <0xC0) { intTmpi = Bitconverter.toint32 (New byte[] { (byte) connection. ReadByte (), tmp[3],0,0},0); Count= Tmpi ^0x8000; } Else { if(tmp[3] <0xE0) {tmp[2] = (byte) connection. ReadByte (); intTmpi = Bitconverter.toint32 (New byte[] { (byte) connection. ReadByte (), tmp[2], tmp[3],0},0); Count= Tmpi ^0xc00000; } Else { if(tmp[3] <0xF0) {tmp[2] = (byte) connection. ReadByte (); tmp[1] = (byte) connection. ReadByte (); intTmpi = Bitconverter.toint32 (New byte[] { (byte) connection. ReadByte (), tmp[1], tmp[2], tmp[3] },0); Count= Tmpi ^0xe0000000; } Else { if(tmp[3] ==0xF0) {tmp[3] = (byte) connection. ReadByte (); tmp[2] = (byte) connection. ReadByte (); tmp[1] = (byte) connection. ReadByte (); tmp[0] = (byte) connection. ReadByte (); Count= Bitconverter.toint32 (TMP,0); } Else { //Error in packet reception, unknown length Break; } } } } } } for(inti =0; I < count; i++) {o+=(Char) connection. ReadByte (); } } returnoutput; } byte[] Encodelength (intDelka) { if(Delka <0x80) { byte[] tmp =bitconverter.getbytes (Delka); return New byte[1] {tmp[0] }; } if(Delka <0x4000) { byte[] tmp = bitconverter.getbytes (Delka |0x8000); return New byte[2] {tmp[1], tmp[0] }; } if(Delka <0x200000) { byte[] tmp = bitconverter.getbytes (Delka |0xc00000); return New byte[3] {tmp[2], tmp[1], tmp[0] }; } if(Delka <0x10000000) { byte[] tmp = bitconverter.getbytes (Delka |0xe0000000); return New byte[4] {tmp[3], tmp[2], tmp[1], tmp[0] }; } Else { byte[] tmp =bitconverter.getbytes (Delka); return New byte[5] {0xF0, tmp[3], tmp[2], tmp[1], tmp[0] }; } } Public stringEncodepassword (stringPassword,stringhash) { byte[] Hash_byte =New byte[Hash. Length/2]; for(inti =0; I <= hash. Length-2; i + =2) {Hash_byte[i/2] = Byte.parse (hash. Substring (I,2), System.Globalization.NumberStyles.HexNumber); } byte[] Heslo =New byte[1+ Password.length +Hash_byte. Length]; heslo[0] =0; Encoding.UTF8.GetBytes (Password.tochararray ()). CopyTo (Heslo,1); Hash_byte. CopyTo (Heslo,1+password.length); Byte[] Hotovo; System.Security.Cryptography.MD5 MD5; MD5=NewSystem.Security.Cryptography.MD5CryptoServiceProvider (); Hotovo=Md5.computehash (Heslo); //Convert encoded bytes back to a ' readable ' string stringNavrat =""; foreach(byteHinchHotovo) {Navrat+ = H.tostring ("X2"); } returnNavrat; } }
C # Ros