0

Good day,

Trust all is well.

I want to duplicate the Move function from Pascal to PHP.

Here is what I have In Pascal:

function Encode(const S: AnsiString): AnsiString;
const
  Map: array [0 .. 63] of Char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
    'abcdefghijklmnopqrstuvwxyz0123456789+/';
var
  i: LongInt;
begin
  i := 0;     ;
  Move(S[1], i, Length(S));
  Result := Map[i mod 64] + Map[(i shr 6) mod 64];
end;

Here is what I have in PHP:

private function Encode($pass)
    {
        $map = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/');
        $i = 0;
        $this->MoveFunction($pass[0], $i, mb_strlen($pass));
        $result = $map[$i % 63] . $map[($i >> 6) % 64];
        return $result;
    }

Now I now know that the Move function is used to copy a section of memory from one place to another, just not sure where to begin and how it would be done. I could not replicate the results from Pascal in PHP. I have tried sub strings ens. to no avail.

The "$this->MoveFunction" is the function that I will need to write in order to duplicate the functionality of the Move function from pascal. I need to use the same outcome of the Move from pascal in order to use the same encryption field from a similar DB.

I think this is an easy way to test in Pascal:

    var
A: array[1..4] of Char;
  B: Integer;
begin
A[1] := 'W';
  A[2] := 'H';
  A[3] := 'A';
  A[4] := 'T';
  B := 5;
  Move(A, B, SizeOf(B));
  showmessage(B.ToString()); // 4718679

Any help would be greatly appreciated.

Thank you in advance.

  • 1
    Weird code, to say the least. I hope you never call `Encode()` with a string with more than 4 chars. – Olivier May 25 '20 at 08:34

1 Answers1

1

Pascal code moves some AnsiChars into 32-bit Int variable. Note that the first char becomes the least significant byte of integer (due to byte order), and result is just equal to

Result := Map[Byte(S[1]) mod 64];

so Move is not needed at all, all other symbols of string aren't involved in work.

If you can cast the first symbol of $pass as byte/int variable in PHP - work is done.

P.S. I see ord() function, so code might look like this:
(I also changed % to bitwise &)

private function Encode($pass)
    {
        $map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
        $i = ord($pass[0]);
        $result = $map[$i & 63];
        return $result;
    }

For shr:

  Result := Map[i mod 64] + Map[(i shr 6) mod 64]; =>

  $a = ord($pass[0]) & 63;
  $b = ord($pass[0]) >> 6;      //two ms bits      

  $b = $b & 3;      //to clear ms bits

  $c = ord($pass[1]) & 15;  //four ls bits  
  $d = $b | ($c << 2);      //combine them
  $result = $map[$a].$map[$d];
MBo
  • 77,366
  • 5
  • 53
  • 86
  • 1
    You don't even need to call `str_split()`. You can access the char from the string directly. – Olivier May 25 '20 at 08:30
  • @MBo, thank you very much the mod seems to work, now the shr part seems like it needs different solution, And I see I forgot to add that into the original question. Map[(Byte(S[1]) shr 10) mod 64] <> Map[(i shr 10) mod 64] – Willem Hamelink May 25 '20 at 09:07
  • @Olivier, thank you I see that now, saves a bit on memory. – Willem Hamelink May 25 '20 at 09:09
  • No, several bits. – AmigoJack May 25 '20 at 09:43
  • @user2319855 This change makes question quite different. Added possible translation – MBo May 25 '20 at 09:44
  • @MBo, Thank you for the SHR code I appreciate it a lot. The one thing I saw was that the result from `Map[(Byte(S[1]) shr 10) mod 64]` differs from the result of `Map[(i shr 10) mod 64]` where the `i` was set by the Move function. – Willem Hamelink May 25 '20 at 10:08
  • 1
    `Byte(S[1]) shr 10` is not real code, because byte shifted by 10 right always gives 0 – MBo May 25 '20 at 10:32
  • @MBO, Sorry about that, I found the original code from him, and edited my question. The shift right that needs to be done by 6 not 10. thus the code will be `Map[(i shr 6) mod 64]`. Thank you for the quick reply and sorry for the confusion on the question. So then do you think I will have to use 2 separate function when using `i` one for the mod and another for the shr? Because the mod one where the Bytes/ord work great. – Willem Hamelink May 25 '20 at 11:15
  • I changed translation to the last version of Pascal code. Is it the last version really? – MBo May 25 '20 at 12:32
  • @MBo, Thank you for the help so far, and man I have still a lot to learn. The values differ from the PHP and the Pascal. Now not sure if it is the interpretation of memory bits ens. Below is the content of the function I use and the results that is generated: `$firstChar = $pass[0]; // $firstChar = E $secondChar = $pass[1]; // $secondChar = d $a = ord($firstChar) & 63; // $a = 5 / Correct $b = ord($firstChar) >> 6; $c = ord($secondChar ) & 63; $d = $b | ($c << 2); // $d = 145 / Wrong (17) $result = $map[$a] . $map[$d];` – Willem Hamelink May 26 '20 at 08:30
  • I made Pascal version of the last PHP code and it works as needed, a b c d == 5 1 4 17. Value 145 means that sign bit is set. PHP right shift `>> ` is arithmetic shift - it widens sign bit, but char `E` has no sign bit! (value is less than 128). Pascal `shr` is not arithmetic - it does not widen sign bit. What are values of `$b` and `$c` in PHP? – MBo May 26 '20 at 09:03
  • @MBo, Thank you very much for the help. That did the trick it looks like. here is the result: `First:E Second:d A:5 B:1 C:4 D:17`. I appreciate all the help you provided, now to get my head 100% around the bits of it all... – Willem Hamelink May 26 '20 at 13:24