[PHP] XOR heel traag op laptop

Pagina: 1
Acties:

Onderwerpen


  • Marijn_S
  • Registratie: Februari 2001
  • Niet online
Ik heb een install-packer en install-unpacker gemaakt. De bedoeling is dat eerst een map met php- en image files worden gepakt en later een gebruiker maar 2 bestanden hoeft te uploaden en dan de install-unpacker kan runnen zodat alles uitgepakt wordt...
Ik wil nu daarbij de inhoud laten XORren en bij de unpack weer XORen(ziet er leuk uit en wil het eigenlijk xorren met een soort license key, ik weet dat het niet heel veilig is enzo). Dit lukt prima op me desktop pc en op in ieder geval een andere pc en een laptop met de volgende functie:

PHP:
1
2
3
4
5
6
7
8
9
function xorData($data,$key) { 
    $j = 0; 
    for($i = 0;$i < strlen($data);$i++) { 
        $data[$i] = $data[$i] ^ $key[$j]; 
        $j++; 
        if($j == strlen($key)) $j = 0; 
    } 
    return $data; 
}


56 files (in totaal 250 kb) worden dan ingepakt en gexorred in iets meer dan een seconde.

Het (enorm vage) probleem is op me laptop het volgende: Kleine files lukken nog, wel heel traag, maar grotere files (30 kb aan plain text bijv.) zijn niet eens klaar in de 30 seconde time-out. Als ik het start pompt PHP (njah Apache.exe) heel even me normale geheugen vol tot 70 ofzo maar me virtual memory blijft optellen tot de 330mb ongeveer en dan is de execution time over.

De PHP versies op beide PC's zijn gelijk (4.23) en ik heb verder totaal geen performance problemen met het uitvoeren van andere scripts op me laptop..

Iemand enig idee?
Desnoods laat ik het xorren maar, maar ben toch erg benieuwd waaraan dit kan liggen :)

ps. GZlib is geen optie omdat dat niet op elke server is geinstalleerd :)

System specs - Ik word blij van knipperende lichtjes.


  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

Wat staat er exact in die $data en die $key? Als dat strings zijn die je binair wilt Xorren, dan moet je met ord() werken volgens mij. 'a' XOR 'b' is namelijk niet geldig. (gok ik)
Daarnaast kun je je strlen functies wel buiten de loop halen. Scheelt allicht.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
function xorData($data,$key) { 
    $j = 0; 
    $keylen = strlen($key);
    $datalen = strlen($data);

    for($i = 0;$i < $datalen;$i++) { 
        $data[$i] = chr(ord($data[$i]) ^ ord($key[$j])); 
        $j++; 
        $j %= $keylen; 
    } 
    return $data; 
}


Hoe staat trouwens je errorreporting?

Localhost, sweet localhost


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Waarom schrijf je de installer in php? Het is mischien wel makkelijker, en zeker sneller, om dit in een andere taal te doen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Marijn_S
  • Registratie: Februari 2001
  • Niet online
Janoz schreef op 12 December 2002 @ 11:24:
Waarom schrijf je de installer in php? Het is mischien wel makkelijker, en zeker sneller, om dit in een andere taal te doen.
Ja, dat snap ik. Maar de unpacker is ook in PHP en daarbij heb ik precies hetzelfde probleem. En die kan ik niet in een andere taal doen. Bovendien hoeft het packen maar 1 keer in de zoveel tijd te gebeuren.

Verder:

Mijn error reporting staat op z'n hoogst maar geeft geen errors behalve de execution time error.
En de Xor functie werkt gewoon op 3 computers in ieder geval, packen en unpacken, dus daar ligt het niet aan (chr en ord is overigens niet nodig), de strlen is nog wel een goede tip ja, al zal dat ook echt een fractie uitmaken denk ik.

Ik heb de functie gebruikt die je hierboven noemt maar het geeft geen beter resultaat.

[ Voor 1% gewijzigd door Marijn_S op 12-12-2002 11:40 . Reden: typo ]

System specs - Ik word blij van knipperende lichtjes.


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
function xorData($data,$key) { 
    $j = 0; 
    $keylen = strlen($key);
    $datalen = strlen($data);

    for($i = 0;$i < $datalen;$i++) { 
        $data[$i] = chr(ord($data[$i]) ^ ord($key[$j])); 
        $j++; 
        if($j == $keylen)
             $j = 0; 
    } 
    return $data; 
}

Als je dan toch gaat optimaliseren doe dan ook geen overbodige (kostbare) delingen :)

  • Marijn_S
  • Registratie: Februari 2001
  • Niet online
Ik heb even mijn originele functie genomen en de 2 die jullie gaven maar die zijn allebei langzamer :)

70 kb plain text:
ACM: 0.58742
kvdveer: 0.59183
Ik: 0.50771

dus ik hou het maar even bij me eigen functie :)

Alleen nu weet ik nog niet waarom het zo gigantisch traag is op me laptop. Kan het aan een PHP configuratie liggen? Kan me echt niet voorstellen waarom dit gebeurd.

edit: Ik zie wel dat de strlen buiten de loop gebruiken toch ook weer wat scheelt dus dat hou ik er dan wel in

[ Voor 13% gewijzigd door Marijn_S op 12-12-2002 14:03 ]

System specs - Ik word blij van knipperende lichtjes.


  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
function xorData($data,$key) { 

    $keylen = strlen($key);
    $datalen = strlen($data);

    if ($datalen > $keylen) {
       $key = str_pad($key,$datalen,chr(0x00)); 
    } else {
       $data =  str_pad($data,$keylen,chr(0x00)); 
    }
     return ($data ^ $key);
}


Dit werkt gewoon voor strings, niks geen ord e.d. nodig.

Overigens, kan je ook even meten hoe snel deze functie is?

Ik ben namelijk wel erg benieuwd :-)

[ Voor 15% gewijzigd door stekkel op 12-12-2002 23:57 ]


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:22
Dat moet iets anders, stekkel. De key moet herhaald worden totdat die even lang is als de gegevens:

PHP:
1
2
$key = str_pad($key, strlen($data), $key);
return ($data ^ $key);


Wat er nu gebeurt als $key langer is dan $data, weet ik niet. :p

Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
Soultaker schreef op 13 December 2002 @ 12:11:
Dat moet iets anders, stekkel. De key moet herhaald worden totdat die even lang is als de gegevens:

PHP:
1
2
$key = str_pad($key, strlen($data), $key);
return ($data ^ $key);


Wat er nu gebeurd als $key langer is dan $data, weet ik niet. :p
ik maak de key net zo lang als data en doe een str_pad met chr(0x00), andersom wordt ook gechecked.

Wat jij doet klopt niet, om tot een werkende xor te komen in php moet je padden met een null bye en niet met de key.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:22
stekkel schreef op 13 December 2002 @ 12:21:
Wat jij doet klopt niet, om tot een werkende xor te komen in php moet je padden met een null bye en niet met de key.
Ik ken de xor-constructie met strings niet, maar ik neem aan dat die de xor-operatie per karakter uitvoert; "\0\1\2" ^ "aaa" wordt dus "abc". Als deze aanname klopt, dan blijkt uit Cerberus' algoritme dat 'ie de key wil 'herbruiken' tot alle gegevens gecodeerd zijn. (Vandaar de "if $j == length($key) $j = 0" clausule).

[ Voor 8% gewijzigd door Soultaker op 13-12-2002 12:26 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

stekkel schreef op 13 december 2002 @ 12:21:
ik maak de key net zo lang als data en doe een str_pad met chr(0x00), andersom wordt ook gechecked.

Dat klinkt niet echt efficient voor files van 2MB ;)

ipv met 1 lange string ga je dan met 2 lange strings werken...
Voor relatief kleine data zal het wellicht sneller zijn, maar verder?
Soultaker schreef op 13 december 2002 @ 12:26:
Ik ken de xor-constructie met strings niet, maar ik neem aan dat die de xor-operatie per karakter uitvoert; "\0\1\2" ^ "aaa" wordt dus "abc". Als deze aanname klopt, dan blijkt uit Cerberus' algoritme dat 'ie de key wil 'herbruiken' tot alle gegevens gecodeerd zijn. (Vandaar de "if $j == length($key) $j = 0" clausule).
Dan moet er dus str_repeat gebruikt worden :)
Maar die is wel wat vervelender toepasbaar.

[ Voor 39% gewijzigd door ACM op 13-12-2002 12:32 ]


Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
Soultaker schreef op 13 December 2002 @ 12:26:
[...]

Ik ken de xor-constructie met strings niet, maar ik neem aan dat die de xor-operatie per karakter uitvoert; "\0\1\2" ^ "aaa" wordt dus "abc". Als deze aanname klopt, dan blijkt uit Cerberus' algoritme dat 'ie de key wil 'herbruiken' tot alle gegevens gecodeerd zijn. (Vandaar de "if $j == length($key) $j = 0" clausule).
Aha, goed punt. Ik had weer eens niet goed gekeken :-(

Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
ACM schreef op 13 December 2002 @ 12:31:

[...]

Dat klinkt niet echt efficient voor files van 2MB ;)

ipv met 1 lange string ga je dan met 2 lange strings werken...
Voor relatief kleine data zal het wellicht sneller zijn, maar verder?
[...]

Dan moet er dus str_repeat gebruikt worden :)
Maar die is wel wat vervelender toepasbaar.
str_repeat zal inderdaad we sneller zijn.

De reden dat ik afzie van de loop is dat ik uit ervaring weet dat wanneer mogelijk je altijd php functies moet gebruiken die hetzelfde doen.

Die functies zijn namelijk intern geoptimaliseerd en daarom sneller dan zelf handmatig byte for byte te xor'en (nieuw woord :) )

Ik heb nogal veel imap-parsers geschreven die in eerste instantie ook loops gebruikte en de data byte for byte bekeek. Theoretisch is dit het snelst maar na wat testjes bleek dat de gedeeltes waar ik gebruik kon maken van interne functies als strpos e.d. (doet intern precies hetzelfde) alles in een keer een stuk sneller bleek te zijn.

[ Voor 4% gewijzigd door stekkel op 13-12-2002 12:41 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

stekkel schreef op 13 December 2002 @ 12:39:
De reden dat ik afzie van de loop is dat ik uit ervaring weet dat wanneer mogelijk je altijd php functies moet gebruiken die hetzelfde doen.

Klopt, maar als je daardoor 2x zoveel data gebruikt voor je gereken kan dat een flink probleem opleveren.

Anderzijds is php sowieso al niet zo efficient met geheugen, dus het kan de moeite van het proberen waard zijn.

Acties:
  • 0 Henk 'm!

  • Marijn_S
  • Registratie: Februari 2001
  • Niet online
Dit alles verklaard alleen niet waarom het script het goed doet op 3 pc's en niet op me laptop :)
Zal in ieder geval even naar de optimalisaties kijken maar het zal weinig uitmaken denk ik (voor me laptop dan, heel lang of iets minder heel lang).
Het is niet van belang dat het iets sneller gaat dus maar dat ik erachter kom waarom het op me laptop zo gigantisch brak loopt.

System specs - Ik word blij van knipperende lichtjes.


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

"T-Bird 1,33 GHz | 256 + 512mb DDR PC2100"

hoe verhoud je laptop zich tot dat systeem?
En draai je het overal in apache + php onder windows?

Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
wanneer het geheugen het probleem is dan moet je slimmer omgaan met je data stream. Je kan bijvoorbeeld per 1024 bytes xorren, dat wegschrijven en de volgende 1024 bytes pakken. M.a.w. niet eerst alles in een buffer inlezen.

Acties:
  • 0 Henk 'm!

  • Marijn_S
  • Registratie: Februari 2001
  • Niet online
Mijn laptop is een 700mhz ding met 192mb ram.
Op mijn laptop heb ik PHPdev423 geinstalleerd (apache + php 4.23 + mysql is dat).
Op mijn desktop heb ik alles appart geinstalleerd. Apache, PHP 4.23 ook en MySQL.

De andere pc's zijn een 1 ghz desktop en een 750 mhz laptop, waar respectievelijk phpdev en ook los alles geinstalleerd op draait.

Het geheugen zou geen probleem moeten zijn. Het lijkt gewoon of hij in een endless loop komt op me laptop omdat hij gewoon me virtual memory vol blijft pompen.
Ik ga het later nog even proberen met een kleinere buffer dan, al vrees ik dat het niet veel uitmaakt :)

System specs - Ik word blij van knipperende lichtjes.

Pagina: 1