C# to PHP conversion

Discussion in 'Programming' started by esgllcinc, Nov 3, 2012.

  1. #1
    Do anyone know how to translate this code from C# to PHP?

    private UInt32 seed;
    private void srand(UInt32 newSeed)
    {
        seed = newSeed;
    }
    
    private UInt32 rand()
    {
        seed = ((0x41c64e6d * seed + 0x6073)) & 4294967295L;
        return seed >> 16;
    }
    
    private void encrypt(bool inbag, byte[] pks2)
    {
        UInt32 pid = 0;
        UInt16 checksum = 0;
        pid = BitConverter.ToUInt32(pks2, 0);
        checksum = BitConverter.ToUInt16(pks2, 6);
        int order = (pid >> (13) & 31) % 24;
        string firstblock = null;
        string secondblock = null;
        string thirdblock = null;
        string fourthblock = null;
        switch (order) {
            case 0:
                firstblock = "A";
                secondblock = "B";
                thirdblock = "C";
                fourthblock = "D";
                break;
            case 1:
                firstblock = "A";
                secondblock = "B";
                thirdblock = "D";
                fourthblock = "C";
                break;
            case 2:
                firstblock = "A";
                secondblock = "C";
                thirdblock = "B";
                fourthblock = "D";
                break;
            case 3:
                firstblock = "A";
                secondblock = "C";
                thirdblock = "D";
                fourthblock = "B";
                break;
            case 4:
                firstblock = "A";
                secondblock = "D";
                thirdblock = "B";
                fourthblock = "C";
                break;
            case 5:
                firstblock = "A";
                secondblock = "D";
                thirdblock = "C";
                fourthblock = "B";
                break;
            case 6:
                firstblock = "B";
                secondblock = "A";
                thirdblock = "C";
                fourthblock = "D";
                break;
            case 7:
                firstblock = "B";
                secondblock = "A";
                thirdblock = "D";
                fourthblock = "C";
                break;
            case 8:
                firstblock = "B";
                secondblock = "C";
                thirdblock = "A";
                fourthblock = "D";
                break;
            case 9:
                firstblock = "B";
                secondblock = "C";
                thirdblock = "D";
                fourthblock = "A";
                break;
            case 10:
                firstblock = "B";
                secondblock = "D";
                thirdblock = "A";
                fourthblock = "C";
                break;
            case 11:
                firstblock = "B";
                secondblock = "D";
                thirdblock = "C";
                fourthblock = "A";
                break;
            case 12:
                firstblock = "C";
                secondblock = "A";
                thirdblock = "B";
                fourthblock = "D";
                break;
            case 13:
                firstblock = "C";
                secondblock = "A";
                thirdblock = "D";
                fourthblock = "B";
                break;
            case 14:
                firstblock = "C";
                secondblock = "B";
                thirdblock = "A";
                fourthblock = "D";
                break;
            case 15:
                firstblock = "C";
                secondblock = "B";
                thirdblock = "D";
                fourthblock = "A";
                break;
            case 16:
                firstblock = "C";
                secondblock = "D";
                thirdblock = "A";
                fourthblock = "B";
                break;
            case 17:
                firstblock = "C";
                secondblock = "D";
                thirdblock = "B";
                fourthblock = "A";
                break;
            case 18:
                firstblock = "D";
                secondblock = "A";
                thirdblock = "B";
                fourthblock = "C";
                break;
            case 19:
                firstblock = "D";
                secondblock = "A";
                thirdblock = "C";
                fourthblock = "B";
                break;
            case 20:
                firstblock = "D";
                secondblock = "B";
                thirdblock = "A";
                fourthblock = "C";
                break;
            case 21:
                firstblock = "D";
                secondblock = "B";
                thirdblock = "C";
                fourthblock = "A";
                break;
            case 22:
                firstblock = "D";
                secondblock = "C";
                thirdblock = "A";
                fourthblock = "B";
                break;
            case 23:
                firstblock = "D";
                secondblock = "C";
                thirdblock = "B";
                fourthblock = "A";
                break;
        }
        int z = 0;
        int v = 8;
        //Block A
        UInt16[] blocka = new UInt16[17];
        while (z < 16) {
            blocka[z] = BitConverter.ToUInt16(pks2, v);
            z = z + 1;
            v = v + 2;
        }
        z = 0;
        v = 40;
        //Block B
        UInt16[] blockb = new UInt16[17];
        while (z < 16) {
            blockb[z] = BitConverter.ToUInt16(pks2, v);
            z = z + 1;
            v = v + 2;
        }
        z = 0;
        //Block C
        v = 72;
        UInt16[] blockc = new UInt16[17];
        while (z < 16) {
            blockc[z] = BitConverter.ToUInt16(pks2, v);
            z = z + 1;
            v = v + 2;
        }
        z = 0;
        //Block D
        UInt16[] blockd = new UInt16[17];
        v = 104;
        while (z < 16) {
            blockd[z] = BitConverter.ToUInt16(pks2, v);
            z = z + 1;
            v = v + 2;
        }
        z = 0;
        UInt16[] inbagb = new UInt16[43];
        v = 136;
        z = 0;
        while (z < 42) {
            inbagb[z] = BitConverter.ToUInt16(pks2, v);
            z = z + 1;
            v = v + 2;
        }
        z = 0;
        srand(checksum);
        UInt16[] byter = new UInt16[17];
        z = 0;
        v = 8;
        switch (firstblock) {
            case "A":
                while (z < 16) {
                    byter[z] = blocka[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "B":
                while (z < 16) {
                    byter[z] = blockb[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "C":
                while (z < 16) {
                    byter[z] = blockc[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "D":
                while (z < 16) {
                    byter[z] = blockd[z] ^ rand();
                    z = z + 1;
                }
                break;
        }
        z = 0;
        v = 8;
        while (z < 16) {
            pks2[v] = byter[z] & 255;
            pks2[v + 1] = byter[z] >> 8;
            z = z + 1;
            v = v + 2;
        }
        z = 0;
        v = 40;
        switch (secondblock) {
            case "A":
                while (z < 16) {
                    byter[z] = blocka[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "B":
                while (z < 16) {
                    byter[z] = blockb[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "C":
                while (z < 16) {
                    byter[z] = blockc[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "D":
                while (z < 16) {
                    byter[z] = blockd[z] ^ rand();
                    z = z + 1;
                }
                break;
        }
        z = 0;
        while (z < 16) {
            pks2[v] = byter[z] & 255;
            pks2[v + 1] = byter[z] >> 8;
            z = z + 1;
            v = v + 2;
        }
        z = 0;
        v = 72;
        switch (thirdblock) {
            case "A":
                while (z < 16) {
                    byter[z] = blocka[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "B":
                while (z < 16) {
                    byter[z] = blockb[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "C":
                while (z < 16) {
                    byter[z] = blockc[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "D":
                while (z < 16) {
                    byter[z] = blockd[z] ^ rand();
                    z = z + 1;
                }
                break;
        }
        z = 0;
        while (z < 16) {
            pks2[v] = byter[z] & 255;
            pks2[v + 1] = byter[z] >> 8;
            z = z + 1;
            v = v + 2;
        }
        z = 0;
        v = 104;
        switch (fourthblock) {
            case "A":
                while (z < 16) {
                    byter[z] = blocka[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "B":
                while (z < 16) {
                    byter[z] = blockb[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "C":
                while (z < 16) {
                    byter[z] = blockc[z] ^ rand();
                    z = z + 1;
                }
                break;
            case "D":
                while (z < 16) {
                    byter[z] = blockd[z] ^ rand();
                    z = z + 1;
                }
                break;
        }
        z = 0;
        while (z < 16) {
            pks2[v] = byter[z] & 255;
            pks2[v + 1] = byter[z] >> 8;
            z = z + 1;
            v = v + 2;
        }
        z = 0;
        //inbag
        v = 136;
        if (inbag == true) {
            srand(pid);
            z = 0;
            UInt16[] inbagbytes = new UInt16[43];
            while (z < 42) {
                inbagbytes[z] = (inbagb[z]) ^ (rand());
                z = z + 1;
            }
            z = 0;
            v = 136;
            while (z < 42) {
                pks2[v] = inbagbytes[z] & 255;
                pks2[v + 1] = inbagbytes[z] >> 8;
                z = z + 1;
                v = v + 2;
            }
        }
        z = 0;
        return pks2;
    }
    Code (markup):
    Your help will be appreciated!
     
    Solved! View solution.
    esgllcinc, Nov 3, 2012 IP
  2. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #2
    Not exactly rocket science -- mostly it's just a matter of stripping out all the typecasting, putting $ before all variable names, and making sure since this appears to be using bitwise operations that you strip off any excess data since php has no strict/predictable typecasting rules.

    Though... damn that's some ugly C code given the "long form" maths, completely pointless 'sRand function... pointless zero assignments on declarations when it's set to a value after...

    Also the bitConverter class might be a bit tricky to deal with since that's an oddball typecasting function specific to C# that other languages would have no equivalent. Byte-wise operations and PHP aren't exactly buddies with PHP's complete lack of pointers and proper typecasting.

    I'm also seeing a lot of uninitialized values in there -- so I'm skeptical the original code would even work right, though I'm not as well versed in C# as I probably should be.

    I'm on the laptop right now, but when I'm back at my workstation I'll see if I can at least get you started on this... though again I'm not convinced the original code actually works given a few... faux-pas in the code like not initializing the values in certain array elements.

    Rewriting the original to make it a HELL of a lot less code would also probably be a good start.
     
    deathshadow, Nov 4, 2012 IP
  3. #3
    I tossed together a rewrite, this SHOULD be functionally identical, but don't hold me to that as the original was... well... very poorly written.

    
    class encrypt {
    
    	private static
    		$encryptSeed=0,
    		// lookup table faster and easier than massive switch statement
    		$encryptOrders = [
    			[0,1,2,3],[0,1,3,2],[0,2,1,3],[0,2,3,1],[0,3,1,2],[0,3,2,1],
    			[1,0,2,3],[1,0,3,2],[1,2,0,3],[1,2,3,0],[1,3,0,2],[1,3,2,0],
    			[2,0,1,3],[2,0,3,1],[2,1,0,3],[2,1,3,0],[2,3,0,1],[2,3,1,0],
    			[3,0,1,2],[3,0,2,1],[3,1,0,2],[3,1,2,0],[3,2,0,1],[3,2,1,0]
    		],
    		$inData,
    		$result;
    		
    	public static function doIt( $inBag, &$data ) {
    	
    		// make private pointer for subroutine use
    		self::$inData = &$data;
    		
    		// copy first ten bytes as they are unchanged
    		self::$result=subStr($data,0,10);
    		
    		$pid = self::readWord(0);
    		$order = self::$encryptOrders[(($pid >> 13) & 31) % 24];
    		self::$encryptSeed = self::readWord(6); // checksum
    		
    		for ($t=0; $t<3; $t++) self::encryptBlock( 8 + 32 * $order[$t], 16 );
    		if ($inBag) {
    			self::$encryptSeed = $pid;
    			self::encryptBlock( 136, 42);
    			$t=178;
    		} else $t=136;
    		
    		// copy any extra data at end unchanged
    		if ($t<strlen($data)) self::$result.=subStr($data,$t);
    		
    		return self::$result;
    		
    	} // method doIt
    
    	private static function encryptRand() {
    		self::$encryptSeed = (
    			(0x41c64e6d * self::$encryptSeed + 0x6073)
    		) & 4294967295;
    		return self::$encryptSeed >> 16;
    	} // method encryptRand
    
    	private static function readByte( $start ) {
    		return (
    			(ord(self::$inData[$start]) << 8) +
    			ord(self::$inData[$start+1])
    		);
    	} // method readByte
    
    	private static function readWord( $start ) {
    		return (
    			(ord(self::$inData[$start]) << 24) +
    			(ord(self::$inData[$start+1]) << 16) +
    			(ord(self::$inData[$start+2]) << 8) +
    			ord(self::$inData[$start+3])
    		);
    	} // method readWord
    	
    	private static function encryptBlock( $read, $count ) {
    		$end = $read + ($count * 2);
    		do {
    			$temp = self::readByte($read) ^ self::encryptRand();
    			self::$result.=chr($temp & 0x00FF);
    			self::$result.=(chr($temp >>8) & 0x00FF);
    			$read += 2;
    		} while ($read < $end);
    	} // method encryptBlock
    	
    } // class encrypt
    
    Code (markup):
    made it a singleton, so everything is nice and contained in it's own namespace.

    If you had some sample before and after data, I'd be able to dial in better if I'm even CLOSE to deciphering the original's purpose.
     
    Last edited: Nov 4, 2012
    deathshadow, Nov 4, 2012 IP
  4. esgllcinc

    esgllcinc Peon

    Messages:
    14
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Unfourtunately I cannot upload the file, but here is the file content in hex

    ENCRYPTED:

    87 4B FE 0C 00 00 5F 0F 6A 07 B2 AA 6F 5F 73 18 57 72 B8 6A 6C 68 BB 74 E0 90 3E 5F 6E 5C 97 15 5C 09 39 51 C4 3E 85 0B 88 D3 B2 60 36 3F 11 77 65 BA 1B E1 D7 F7 3C 09 63 C1 B7 5D E1 B7 8E 7C 90 ED DB 93 92 C2 76 76 58 3B 1C 8E 30 D1 8E 2D F0 C7 42 22 3D DA 56 B9 06 2F A7 FA 4A 21 02 33 B1 FA 68 B8 B2 5B 91 2E 32 0C 5C 65 14 79 01 6E 02 3A 43 B8 FC 47 F3 D1 3F 8C 3B D6 0D 74 1E 2E E8 75 56 C0 0E 9B D2 8A

    BEFORE:

    87 4B FE 0C 00 00 5F 0F 3D 00 3A 01 2A 2C 63 F3 14 2C 10 00 FF 06 00 02 55 55 55 55 55 55 00 00 00 00 00 00 00 00 00 00 AA 01 38 00 66 01 BB 00 0A 05 0A 0A 00 00 00 00 FF FF FF 3F 00 00 00 00 00 15 00 00 00 00 00 00 52 00 61 00 6E 00 65 00 FF FF 00 00 A1 48 02 0C FF E0 FF FF FF FF 00 04 00 00 00 00 00 00 00 00 45 00 53 00 47 00 FF FF 00 00 00 00 00 00 FF FF 00 00 00 0B 03 06 00 00 00 00 00 04 1F 00 00 00
     
    esgllcinc, Nov 9, 2012 IP