C# to PHP

Discussion in 'Programming' started by esgllcinc, Sep 20, 2012.

  1. #1
    Hello, do anyone know how to convert the C# code to PHP?

    
    ms.Position = 0x08;
    UInt32 Checksum = 0;
    for (int j = 0; j < 64; j++)
    {
        Checksum += Convert.ToUInt32(ms.ReadByte()) + (Convert.ToUInt32(ms.ReadByte()) * 0x100);
        Checksum = (Checksum - ((Checksum / 0x10000) * 0x10000));
    }
    
    ms.Position = 0x06;
    ms.WriteByte(Convert.ToByte((Checksum) - ((Checksum / 0x100) * 0x100)));
    ms.WriteByte(Convert.ToByte(Checksum / 0x100));
    
    Code (markup):
     
    Solved! View solution.
    esgllcinc, Sep 20, 2012 IP
  2. #2
    I'm assuming ms is a filestream... It would be nice if we could see where that's defined/opened, and closed.

    Also that's crappy code, since divides and multiplies are slow and really all you want to do there is strip off the bottom bits or shift the bits -- and that's & and <<'s job.

    The original should have been written more like this:
    
    ms.Position = 0x08;
    UInt32 Checksum = 0;
    for (int j = 0; j < 64; j++) {
    	Checksum += Convert.ToUInt32(ms.ReadByte() + (ms.ReadByte() << 8));
    	Checksum = Checksum & 0x0000FFFF;
    }
    
    ms.Position = 0x06;
    ms.WriteByte(Convert.ToByte(Checksum & 0x000000FF));
    ms.WriteByte(Convert.ToByte(Checksum >> 8));
    Code (markup):
    Though I'm not sure all those conversions are necessary since readbyte returns int... hell if you typecase to uInt16...

    and in PHP (with a file open and close) it would be something like this:
    
    //	I'm going to assume "ms" in your code is a filestream
    $handle=fopen('filename','r+');
    
    fseek($handle, 0x08);
    // faster to read all 128 bytes at once
    $temp=fread($handle, 128);
    $t=0;
    $checksum = 0;
    do {
    	$checksum += ord($temp[$t++]) + (ord($temp[$t++]) << 8);
    	$checksum = $checksum & 0x0000FFFF;
    } while $t<128;
    
    fseek($handle, 0x06);
    fwrite($handle, chr($checksum & 0x000000FF).chr($checksum >> 8));
    
    fclose($handle);
    Code (markup):
    I'm always a bit shocked to see such needlessly convoluted methods of simply pulling a byte or word from a complex data set.
     
    Last edited: Sep 22, 2012
    deathshadow, Sep 22, 2012 IP
  3. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #3
    Yeah, in the original, typecasting to unsigned 16 bit works wonders... as it guts out the need for the &. Shame there's no equivalent in PHP.

    
    ms.Position = 0x08;
    UInt16 Checksum = 0;
    for (int j = 0; j < 64; j++) {
    	Checksum+=ms.ReadByte()+(ms.ReadByte()<<8);
    }
    
    ms.Position = 0x06;
    ms.WriteByte(Convert.ToByte(Checksum & 0x00FF));
    ms.WriteByte(Convert.ToByte(Checksum >> 8));
    
    Code (markup):
    Far, FAR simpler.
     
    deathshadow, Sep 22, 2012 IP
  4. esgllcinc

    esgllcinc Peon

    Messages:
    14
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Wow! It worked, thanks!
     
    esgllcinc, Sep 22, 2012 IP
  5. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #5
    Oh, for laughs, it just occurred to me I have the exact same checksum in a DOS program I wrote in turbo pascal -- as inline 16 bit x86 assembly.

    
    type
    	pByte=^byte;
    
    function checksum16(data:pByte):word; assembler;
    asm
    	xor  bx,bx
    	les  di,data
    	mov  cx,64
    @repeat:
    	lodsw
    	xchg ah,al // correct for little endian
    	add  bx,ax
    	loop @repeat
    	mov  ax,bx // TP inline ASM uses AX for function retval
    end;
    
    Code (markup):
    What makes it funnier is that the smaller 'backwards compatible' 8 and 16 bit versions of the registers actually make x86 far, far faster and more efficient at this than 'true' 32 bit or 64 bit processors -- basically what the RISC-tards harp on CISC about, is what makes this superior to the endless "shifts" and "ands" you'd have to do on something like ARM or PPC.

    Gah, I've been at this **** for far, FAR too many years.
     
    Last edited: Sep 22, 2012
    deathshadow, Sep 22, 2012 IP
  6. Rukbat

    Rukbat Well-Known Member

    Messages:
    2,908
    Likes Received:
    37
    Best Answers:
    51
    Trophy Points:
    125
    #6
    And when you get to that point, you always have the same thing written in some other language for some other purpose, don't you?

    Good programmers steal from great programmers.
    Great programmers steal from themselves.

    Old programmers don't die, we just shift too many places.
     
    Rukbat, Oct 1, 2012 IP
  7. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #7
    Gets even stranger when you look at that code today, and see further optimizations for it -- like switching the XCHG so that AL is first, since that shaves a byte and as much as 5 clocks (4 for the fetch, 1 EU) off it on the 8088. (most x86 instructions are faster if you make the lowest order bits of the accumulator the main parameter -- AL, AX, EAX)

    Quite literally
    XCHG AH,AL = 2 bytes, 4 EU clocks
    XCHG AL,AH = 1 byte, 3 EU clocks

    ... and when you figure that fetching a byte takes 4 clock cycles on the 8088/8086 -- clocks that can be spent while the EU is running... that LODSW uses 8 cycles of BIU and 16 cycles total... that change would free up 4 more clocks to fill the BIU with the first byte of the ADD after, the remaining byte only taking one more clock off the XCHG's EU time... wow, that would actually shave 8 clock cycles off inside the loop!
     
    deathshadow, Oct 1, 2012 IP
  8. Rukbat

    Rukbat Well-Known Member

    Messages:
    2,908
    Likes Received:
    37
    Best Answers:
    51
    Trophy Points:
    125
    #8
    What really gets me is that this is really what programming is all about, but it's probably way over the heads of 95% (or more) of the "programmers" posting here.

    Ever jump to the second byte of an instruction, because you manipulated the code that way, so the operand and following instruction's opcode formed an opcode and operand that the program could use - shaving 2 bytes off the code?

    Or set up a "pseudo-cmp" by subtracting in an 8048, because it has no compare (but, saving grace, POP doesn't affect flags)?

    Programming used to be fun, now it's dragging controls onto forms.
     
    Rukbat, Oct 1, 2012 IP