Merge pull request #1 from danog/analysis-zdjEEJ

Applied fixes from StyleCI
This commit is contained in:
Daniil Gentili 2016-07-14 15:18:13 +02:00 committed by GitHub
commit 42e8d105d9
19 changed files with 1966 additions and 1516 deletions

View File

@ -18,7 +18,8 @@
* Comments, Questions? Contact the author at cody [at] wshost [dot] net * Comments, Questions? Contact the author at cody [at] wshost [dot] net
*/ */
class AES { class AES
{
// The number of 32-bit words comprising the plaintext and columns comrising the state matrix of an AES cipher. // The number of 32-bit words comprising the plaintext and columns comrising the state matrix of an AES cipher.
private static $Nb = 4; private static $Nb = 4;
// The number of 32-bit words comprising the cipher key in this AES cipher. // The number of 32-bit words comprising the cipher key in this AES cipher.
@ -27,7 +28,7 @@ class AES {
private $Nr; private $Nr;
// The S-Box substitution table. // The S-Box substitution table.
private static $sBox = array( private static $sBox = [
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
@ -59,11 +60,11 @@ class AES {
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
); ];
// The inverse S-Box substitution table. // The inverse S-Box substitution table.
private static $invSBox = array( private static $invSBox = [
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
@ -95,11 +96,11 @@ class AES {
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
); ];
// Log table based on 0xe5 // Log table based on 0xe5
private static $ltable = array( private static $ltable = [
0x00, 0xff, 0xc8, 0x08, 0x91, 0x10, 0xd0, 0x36, 0x00, 0xff, 0xc8, 0x08, 0x91, 0x10, 0xd0, 0x36,
0x5a, 0x3e, 0xd8, 0x43, 0x99, 0x77, 0xfe, 0x18, 0x5a, 0x3e, 0xd8, 0x43, 0x99, 0x77, 0xfe, 0x18,
0x23, 0x20, 0x07, 0x70, 0xa1, 0x6c, 0x0c, 0x7f, 0x23, 0x20, 0x07, 0x70, 0xa1, 0x6c, 0x0c, 0x7f,
@ -131,11 +132,11 @@ class AES {
0x22, 0x88, 0x94, 0xce, 0x19, 0x01, 0x71, 0x4c, 0x22, 0x88, 0x94, 0xce, 0x19, 0x01, 0x71, 0x4c,
0xa5, 0xe3, 0xc5, 0x31, 0xbb, 0xcc, 0x1f, 0x2d, 0xa5, 0xe3, 0xc5, 0x31, 0xbb, 0xcc, 0x1f, 0x2d,
0x3b, 0x52, 0x6f, 0xf6, 0x2e, 0x89, 0xf7, 0xc0, 0x3b, 0x52, 0x6f, 0xf6, 0x2e, 0x89, 0xf7, 0xc0,
0x68, 0x1b, 0x64, 0x04, 0x06, 0xbf, 0x83, 0x38 0x68, 0x1b, 0x64, 0x04, 0x06, 0xbf, 0x83, 0x38,
); ];
// Inverse log table // Inverse log table
private static $atable = array( private static $atable = [
0x01, 0xe5, 0x4c, 0xb5, 0xfb, 0x9f, 0xfc, 0x12, 0x01, 0xe5, 0x4c, 0xb5, 0xfb, 0x9f, 0xfc, 0x12,
0x03, 0x34, 0xd4, 0xc4, 0x16, 0xba, 0x1f, 0x36, 0x03, 0x34, 0xd4, 0xc4, 0x16, 0xba, 0x1f, 0x36,
0x05, 0x5c, 0x67, 0x57, 0x3a, 0xd5, 0x21, 0x5a, 0x05, 0x5c, 0x67, 0x57, 0x3a, 0xd5, 0x21, 0x5a,
@ -167,8 +168,8 @@ class AES {
0x1e, 0xd3, 0x49, 0xe9, 0x9c, 0xc8, 0xc6, 0xc7, 0x1e, 0xd3, 0x49, 0xe9, 0x9c, 0xc8, 0xc6, 0xc7,
0x22, 0x6e, 0xdb, 0x20, 0xbf, 0x43, 0x51, 0x52, 0x22, 0x6e, 0xdb, 0x20, 0xbf, 0x43, 0x51, 0x52,
0x66, 0xb2, 0x76, 0x60, 0xda, 0xc5, 0xf3, 0xf6, 0x66, 0xb2, 0x76, 0x60, 0xda, 0xc5, 0xf3, 0xf6,
0xaa, 0xcd, 0x9a, 0xa0, 0x75, 0x54, 0x0e, 0x01 0xaa, 0xcd, 0x9a, 0xa0, 0x75, 0x54, 0x0e, 0x01,
); ];
// The key schedule in this AES cipher. // The key schedule in this AES cipher.
private $w; private $w;
@ -180,16 +181,18 @@ class AES {
/** constructs an AES cipher using a specific key. /** constructs an AES cipher using a specific key.
*/ */
public function __construct($z) { public function __construct($z)
{
$this->Nk = strlen($z) / 4; $this->Nk = strlen($z) / 4;
$this->Nr = $this->Nk + self::$Nb + 2; $this->Nr = $this->Nk + self::$Nb + 2;
if ($this->Nk != 4 && $this->Nk != 6 && $this->Nk != 8) if ($this->Nk != 4 && $this->Nk != 6 && $this->Nk != 8) {
die("Key is " . ($this->Nk*32) . " bits long. *not* 128, 192, or 256."); die('Key is '.($this->Nk * 32).' bits long. *not* 128, 192, or 256.');
}
$this->Nr = $this->Nk + self::$Nb + 2; $this->Nr = $this->Nk + self::$Nb + 2;
$this->w = array(); // Nb*(Nr+1) 32-bit words $this->w = []; // Nb*(Nr+1) 32-bit words
$this->s = array(array()); // 2-D array of Nb colums and 4 rows $this->s = [[]]; // 2-D array of Nb colums and 4 rows
$this->KeyExpansion($z); // places expanded key in w $this->KeyExpansion($z); // places expanded key in w
} }
@ -201,9 +204,10 @@ class AES {
* encryptBlock() function directly, as the amount of time required * encryptBlock() function directly, as the amount of time required
* to encrypt is linear to the size of the ciphertext. * to encrypt is linear to the size of the ciphertext.
**/ **/
public function encrypt($x) { public function encrypt($x)
$t = ""; // 16-byte block {
$y = ""; // returned cipher text; $t = ''; // 16-byte block
$y = ''; // returned cipher text;
// put a 16-byte block into t // put a 16-byte block into t
$xsize = strlen($x); $xsize = strlen($x);
@ -211,13 +215,14 @@ class AES {
for ($j = 0; $j < 16; $j++) { for ($j = 0; $j < 16; $j++) {
if (($i + $j) < $xsize) { if (($i + $j) < $xsize) {
$t[$j] = $x[$i + $j]; $t[$j] = $x[$i + $j];
} } else {
else
$t[$j] = chr(0); $t[$j] = chr(0);
} }
}
$y .= $this->encryptBlock($t); $y .= $this->encryptBlock($t);
} }
return $y; return $y;
} }
@ -228,21 +233,24 @@ class AES {
* decryptBlock() function directly, as the amount of time required * decryptBlock() function directly, as the amount of time required
* to decrypt is linear to the size of the ciphertext. * to decrypt is linear to the size of the ciphertext.
**/ **/
public function decrypt($y) { public function decrypt($y)
$t = ""; // 16-byte block {
$x = ""; // returned plain text; $t = ''; // 16-byte block
$x = ''; // returned plain text;
// put a 16-byte block into t // put a 16-byte block into t
$ysize = strlen($y); $ysize = strlen($y);
for ($i = 0; $i < $ysize; $i += 16) { for ($i = 0; $i < $ysize; $i += 16) {
for ($j = 0; $j < 16; $j++) { for ($j = 0; $j < 16; $j++) {
if (($i+$j)<$ysize) if (($i + $j) < $ysize) {
$t[$j] = $y[$i + $j]; $t[$j] = $y[$i + $j];
else } else {
$t[$j] = chr(0); $t[$j] = chr(0);
} }
}
$x .= $this->decryptBlock($t); $x .= $this->decryptBlock($t);
} }
return $x; return $x;
} }
@ -250,8 +258,9 @@ class AES {
* @params 16-byte plaintext string * @params 16-byte plaintext string
* @returns 16-byte ciphertext string * @returns 16-byte ciphertext string
**/ **/
public function encryptBlock($x) { public function encryptBlock($x)
$y = ""; // 16-byte string {
$y = ''; // 16-byte string
// place input x into the initial state matrix in column order // place input x into the initial state matrix in column order
for ($i = 0; $i < 4 * self::$Nb; $i++) { for ($i = 0; $i < 4 * self::$Nb; $i++) {
@ -286,8 +295,10 @@ class AES {
$this->addRoundKey($i); $this->addRoundKey($i);
// place state matrix s into y in column order // place state matrix s into y in column order
for ($i=0; $i<4*self::$Nb; $i++) for ($i = 0; $i < 4 * self::$Nb; $i++) {
$y .= chr($this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb]); $y .= chr($this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb]);
}
return $y; return $y;
} }
@ -295,12 +306,14 @@ class AES {
* @params 16-byte ciphertext string * @params 16-byte ciphertext string
* @returns 16-byte plaintext string * @returns 16-byte plaintext string
**/ **/
public function decryptBlock($y) { public function decryptBlock($y)
$x = ""; // 16-byte string {
$x = ''; // 16-byte string
// place input y into the initial state matrix in column order // place input y into the initial state matrix in column order
for ($i=0; $i<4*self::$Nb; $i++) for ($i = 0; $i < 4 * self::$Nb; $i++) {
$this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb] = ord($y[$i]); $this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb] = ord($y[$i]);
}
// add round key // add round key
$this->addRoundKey($this->Nr); $this->addRoundKey($this->Nr);
@ -331,13 +344,14 @@ class AES {
// place state matrix s into x in column order // place state matrix s into x in column order
for ($i = 0; $i < 4 * self::$Nb; $i++) { for ($i = 0; $i < 4 * self::$Nb; $i++) {
// Used to remove filled null characters. // Used to remove filled null characters.
$x .= ($this->s[$i%4][($i-$i%self::$Nb)/self::$Nb] == chr(0) ? "" : chr($this->s[$i%4][($i-$i%self::$Nb)/self::$Nb])); $x .= ($this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb] == chr(0) ? '' : chr($this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb]));
} }
return $x; return $x;
} }
public function __destruct() { public function __destruct()
{
unset($this->w); unset($this->w);
unset($this->s); unset($this->s);
} }
@ -345,9 +359,10 @@ class AES {
/** makes a big key out of a small one /** makes a big key out of a small one
* @returns void * @returns void
**/ **/
private function KeyExpansion($z) { private function KeyExpansion($z)
{
// Rcon is the round constant // Rcon is the round constant
static $Rcon = array( static $Rcon = [
0x00000000, 0x00000000,
0x01000000, 0x01000000,
0x02000000, 0x02000000,
@ -364,8 +379,8 @@ class AES {
0xab000000, 0xab000000,
0x4d000000, 0x4d000000,
0x9a000000, 0x9a000000,
0x2f000000 0x2f000000,
); ];
$temp = 0; // temporary 32-bit word $temp = 0; // temporary 32-bit word
@ -387,10 +402,11 @@ class AES {
for (; $i < self::$Nb * ($this->Nr + 1); $i++) { for (; $i < self::$Nb * ($this->Nr + 1); $i++) {
$temp = $this->w[$i - 1]; $temp = $this->w[$i - 1];
if ($i%$this->Nk == 0) if ($i % $this->Nk == 0) {
$temp = $this->subWord($this->rotWord($temp)) ^ $Rcon[$i / $this->Nk]; $temp = $this->subWord($this->rotWord($temp)) ^ $Rcon[$i / $this->Nk];
else if ($this->Nk > 6 && $i%$this->Nk == 4) } elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
$temp = $this->subWord($temp); $temp = $this->subWord($temp);
}
$this->w[$i] = $this->w[$i - $this->Nk] ^ $temp; $this->w[$i] = $this->w[$i - $this->Nk] ^ $temp;
@ -401,8 +417,9 @@ class AES {
/** adds the key schedule for a round to a state matrix. /** adds the key schedule for a round to a state matrix.
* @returns void * @returns void
**/ **/
private function addRoundKey($round) { private function addRoundKey($round)
$temp = ""; {
$temp = '';
for ($i = 0; $i < 4; $i++) { for ($i = 0; $i < 4; $i++) {
for ($j = 0; $j < self::$Nb; $j++) { for ($j = 0; $j < self::$Nb; $j++) {
@ -421,52 +438,65 @@ class AES {
/** unmixes each column of a state matrix. /** unmixes each column of a state matrix.
* @returns void * @returns void
**/ **/
private function invMixColumns() { private function invMixColumns()
{
$s0 = $s1 = $s2 = $s3 = ''; $s0 = $s1 = $s2 = $s3 = '';
// There are Nb columns // There are Nb columns
for ($i = 0; $i < self::$Nb; $i++) { for ($i = 0; $i < self::$Nb; $i++) {
$s0 = $this->s[0][$i]; $s1 = $this->s[1][$i]; $s2 = $this->s[2][$i]; $s3 = $this->s[3][$i]; $s0 = $this->s[0][$i];
$s1 = $this->s[1][$i];
$s2 = $this->s[2][$i];
$s3 = $this->s[3][$i];
$this->s[0][$i] = $this->mult(0x0e, $s0) ^ $this->mult(0x0b, $s1) ^ $this->mult(0x0d, $s2) ^ $this->mult(0x09, $s3); $this->s[0][$i] = $this->mult(0x0e, $s0) ^ $this->mult(0x0b, $s1) ^ $this->mult(0x0d, $s2) ^ $this->mult(0x09, $s3);
$this->s[1][$i] = $this->mult(0x09, $s0) ^ $this->mult(0x0e, $s1) ^ $this->mult(0x0b, $s2) ^ $this->mult(0x0d, $s3); $this->s[1][$i] = $this->mult(0x09, $s0) ^ $this->mult(0x0e, $s1) ^ $this->mult(0x0b, $s2) ^ $this->mult(0x0d, $s3);
$this->s[2][$i] = $this->mult(0x0d, $s0) ^ $this->mult(0x09, $s1) ^ $this->mult(0x0e, $s2) ^ $this->mult(0x0b, $s3); $this->s[2][$i] = $this->mult(0x0d, $s0) ^ $this->mult(0x09, $s1) ^ $this->mult(0x0e, $s2) ^ $this->mult(0x0b, $s3);
$this->s[3][$i] = $this->mult(0x0b, $s0) ^ $this->mult(0x0d, $s1) ^ $this->mult(0x09, $s2) ^ $this->mult(0x0e, $s3); $this->s[3][$i] = $this->mult(0x0b, $s0) ^ $this->mult(0x0d, $s1) ^ $this->mult(0x09, $s2) ^ $this->mult(0x0e, $s3);
} }
} }
/** applies an inverse cyclic shift to the last 3 rows of a state matrix. /** applies an inverse cyclic shift to the last 3 rows of a state matrix.
* @returns void * @returns void
**/ **/
private function invShiftRows() { private function invShiftRows()
$temp = ""; {
$temp = '';
for ($i = 1; $i < 4; $i++) { for ($i = 1; $i < 4; $i++) {
for ($j=0; $j<self::$Nb; $j++) for ($j = 0; $j < self::$Nb; $j++) {
$temp[($i + $j) % self::$Nb] = $this->s[$i][$j]; $temp[($i + $j) % self::$Nb] = $this->s[$i][$j];
for ($j=0; $j<self::$Nb; $j++) }
for ($j = 0; $j < self::$Nb; $j++) {
$this->s[$i][$j] = $temp[$j]; $this->s[$i][$j] = $temp[$j];
} }
} }
}
/** applies inverse S-Box substitution to each byte of a state matrix. /** applies inverse S-Box substitution to each byte of a state matrix.
* @returns void * @returns void
**/ **/
private function invSubBytes() { private function invSubBytes()
for ($i=0; $i<4; $i++) {
for ($j=0; $j<self::$Nb; $j++) for ($i = 0; $i < 4; $i++) {
for ($j = 0; $j < self::$Nb; $j++) {
$this->s[$i][$j] = self::$invSBox[$this->s[$i][$j]]; $this->s[$i][$j] = self::$invSBox[$this->s[$i][$j]];
} }
}
}
/** mixes each column of a state matrix. /** mixes each column of a state matrix.
* @returns void * @returns void
**/ **/
private function mixColumns() { private function mixColumns()
{
$s0 = $s1 = $s2 = $s3 = ''; $s0 = $s1 = $s2 = $s3 = '';
// There are Nb columns // There are Nb columns
for ($i = 0; $i < self::$Nb; $i++) { for ($i = 0; $i < self::$Nb; $i++) {
$s0 = $this->s[0][$i]; $s1 = $this->s[1][$i]; $s2 = $this->s[2][$i]; $s3 = $this->s[3][$i]; $s0 = $this->s[0][$i];
$s1 = $this->s[1][$i];
$s2 = $this->s[2][$i];
$s3 = $this->s[3][$i];
$this->s[0][$i] = $this->mult(0x02, $s0) ^ $this->mult(0x03, $s1) ^ $this->mult(0x01, $s2) ^ $this->mult(0x01, $s3); $this->s[0][$i] = $this->mult(0x02, $s0) ^ $this->mult(0x03, $s1) ^ $this->mult(0x01, $s2) ^ $this->mult(0x01, $s3);
$this->s[1][$i] = $this->mult(0x01, $s0) ^ $this->mult(0x02, $s1) ^ $this->mult(0x03, $s2) ^ $this->mult(0x01, $s3); $this->s[1][$i] = $this->mult(0x01, $s0) ^ $this->mult(0x02, $s1) ^ $this->mult(0x03, $s2) ^ $this->mult(0x01, $s3);
@ -478,41 +508,49 @@ class AES {
/** applies a cyclic shift to the last 3 rows of a state matrix. /** applies a cyclic shift to the last 3 rows of a state matrix.
* @returns void * @returns void
**/ **/
private function shiftRows() { private function shiftRows()
$temp = ""; {
$temp = '';
for ($i = 1; $i < 4; $i++) { for ($i = 1; $i < 4; $i++) {
for ($j=0; $j<self::$Nb; $j++) for ($j = 0; $j < self::$Nb; $j++) {
$temp[$j] = $this->s[$i][($j + $i) % self::$Nb]; $temp[$j] = $this->s[$i][($j + $i) % self::$Nb];
for ($j=0; $j<self::$Nb; $j++) }
for ($j = 0; $j < self::$Nb; $j++) {
$this->s[$i][$j] = $temp[$j]; $this->s[$i][$j] = $temp[$j];
} }
} }
}
/** applies S-Box substitution to each byte of a state matrix. /** applies S-Box substitution to each byte of a state matrix.
* @returns void * @returns void
**/ **/
private function subBytes() { private function subBytes()
{
for ($i = 0; $i < 4; $i++) { for ($i = 0; $i < 4; $i++) {
for ($j=0; $j<self::$Nb; $j++) for ($j = 0; $j < self::$Nb; $j++) {
$this->s[$i][$j] = self::$sBox[$this->s[$i][$j]]; $this->s[$i][$j] = self::$sBox[$this->s[$i][$j]];
} }
} }
}
/** multiplies two polynomials a(x), b(x) in GF(2^8) modulo the irreducible polynomial m(x) = x^8+x^4+x^3+x+1 /** multiplies two polynomials a(x), b(x) in GF(2^8) modulo the irreducible polynomial m(x) = x^8+x^4+x^3+x+1
* @returns 8-bit value * @returns 8-bit value
**/ **/
private static function mult($a, $b) { private static function mult($a, $b)
{
$sum = self::$ltable[$a] + self::$ltable[$b]; $sum = self::$ltable[$a] + self::$ltable[$b];
$sum %= 255; $sum %= 255;
// Get the antilog // Get the antilog
$sum = self::$atable[$sum]; $sum = self::$atable[$sum];
return ($a == 0 ? 0 : ($b == 0 ? 0 : $sum));
return $a == 0 ? 0 : ($b == 0 ? 0 : $sum);
} }
/** applies a cyclic permutation to a 4-byte word. /** applies a cyclic permutation to a 4-byte word.
* @returns 32-bit int * @returns 32-bit int
**/ **/
private static function rotWord($w) { private static function rotWord($w)
{
$temp = $w >> 24; // put the first 8-bits into temp $temp = $w >> 24; // put the first 8-bits into temp
$w <<= 8; // make room for temp to fill the lower end of the word $w <<= 8; // make room for temp to fill the lower end of the word
self::make32BitWord($w); self::make32BitWord($w);
@ -526,7 +564,8 @@ class AES {
/** applies S-box substitution to each byte of a 4-byte word. /** applies S-box substitution to each byte of a 4-byte word.
* @returns 32-bit int * @returns 32-bit int
**/ **/
private static function subWord($w) { private static function subWord($w)
{
$temp = 0; $temp = 0;
// loop through 4 bytes of a word // loop through 4 bytes of a word
for ($i = 0; $i < 4; $i++) { for ($i = 0; $i < 4; $i++) {
@ -546,9 +585,9 @@ class AES {
/** reduces a 64-bit word to a 32-bit word /** reduces a 64-bit word to a 32-bit word
* @returns void * @returns void
**/ **/
private static function make32BitWord(&$w) { private static function make32BitWord(&$w)
{
// Reduce this 64-bit word to 32-bits on 64-bit machines // Reduce this 64-bit word to 32-bits on 64-bit machines
$w &= 0x00000000FFFFFFFF; $w &= 0x00000000FFFFFFFF;
} }
} }
?>

66
TL.php
View File

@ -1,10 +1,13 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
$__author__ = 'agrigoryev'; $__author__ = 'agrigoryev';
require_once ('os.php'); require_once 'os.php';
class TlConstructor { class TlConstructor
function __construct($json_dict) { {
public function __construct($json_dict)
{
$this->id = (int) $json_dict['id']; $this->id = (int) $json_dict['id'];
$this->type = $json_dict['type']; $this->type = $json_dict['type'];
$this->predicate = $json_dict['predicate']; $this->predicate = $json_dict['predicate'];
@ -26,22 +29,28 @@ class TlConstructor {
} }
} }
} }
class TlMethod { class TlMethod
function __construct($json_dict) { {
public function __construct($json_dict)
{
$this->id = (int) $json_dict['id']; $this->id = (int) $json_dict['id'];
$this->type = $json_dict['type']; $this->type = $json_dict['type'];
$this->method = $json_dict['method']; $this->method = $json_dict['method'];
$this->params = $json_dict['params']; $this->params = $json_dict['params'];
} }
} }
class TLObject extends ArrayObject { class TLObject extends ArrayObject
function __construct($tl_elem) { {
public function __construct($tl_elem)
{
parent::__construct(); parent::__construct();
$this->name = $tl_elem->predicate; $this->name = $tl_elem->predicate;
} }
} }
class TL { class TL
function __construct($filename) { {
public function __construct($filename)
{
$TL_dict = json_decode(file_get_contents($filename), true); $TL_dict = json_decode(file_get_contents($filename), true);
$this->constructors = $TL_dict['constructors']; $this->constructors = $TL_dict['constructors'];
$this->constructor_id = []; $this->constructor_id = [];
@ -61,37 +70,41 @@ class TL {
} }
$this->struct = new \danog\PHP\Struct(); $this->struct = new \danog\PHP\Struct();
} }
function serialize_obj($type_, $kwargs) {
$bytes_io = fopen("php://memory", "rw+b"); public function serialize_obj($type_, $kwargs)
{
$bytes_io = fopen('php://memory', 'rw+b');
if (isset($this->constructor_type[$type_])) { if (isset($this->constructor_type[$type_])) {
$tl_constructor = $this->constructor_type[$type_]; $tl_constructor = $this->constructor_type[$type_];
} } else {
else
{
throw new Exception(sprintf('Could not extract type: %s', $type_)); throw new Exception(sprintf('Could not extract type: %s', $type_));
} }
fwrite($bytes_io, $this->struct->pack('<i', $tl_constructor->id)); fwrite($bytes_io, $this->struct->pack('<i', $tl_constructor->id));
foreach ($tl_constructor->params as $arg) { foreach ($tl_constructor->params as $arg) {
$this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]); $this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
} }
return fread_all($bytes_io); return fread_all($bytes_io);
} }
function serialize_method($type_, $kwargs) {
$bytes_io = fopen("php://memory", "rw+b"); public function serialize_method($type_, $kwargs)
{
$bytes_io = fopen('php://memory', 'rw+b');
if (isset($this->method_name[$type_])) { if (isset($this->method_name[$type_])) {
$tl_method = $this->method_name[$type_]; $tl_method = $this->method_name[$type_];
} } else {
else
{
throw new Exception(sprintf('Could not extract type: %s', $type_)); throw new Exception(sprintf('Could not extract type: %s', $type_));
} }
fwrite($bytes_io, $this->struct->pack('<i', $tl_method->id)); fwrite($bytes_io, $this->struct->pack('<i', $tl_method->id));
foreach ($tl_method->params as $arg) { foreach ($tl_method->params as $arg) {
$this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]); $this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
} }
return fread_all($bytes_io); return fread_all($bytes_io);
} }
function serialize_param($bytes_io, $type_, $value) {
public function serialize_param($bytes_io, $type_, $value)
{
if (($type_ == 'int')) { if (($type_ == 'int')) {
assert(is_numeric($value)); assert(is_numeric($value));
assert(strlen(decbin($value)) <= 32); assert(strlen(decbin($value)) <= 32);
@ -107,19 +120,21 @@ class TL {
if (($l < 254)) { if (($l < 254)) {
fwrite($bytes_io, $this->struct->pack('<b', $l)); fwrite($bytes_io, $this->struct->pack('<b', $l));
fwrite($bytes_io, $value); fwrite($bytes_io, $value);
fwrite($bytes_io, pack("@".((-$l - 1) % 4))); fwrite($bytes_io, pack('@'.((-$l - 1) % 4)));
} else { } else {
fwrite($bytes_io, string2bin('\xfe')); fwrite($bytes_io, string2bin('\xfe'));
fwrite($bytes_io, substr($this->struct->pack('<i', $l), null, 3)); fwrite($bytes_io, substr($this->struct->pack('<i', $l), null, 3));
fwrite($bytes_io, $value); fwrite($bytes_io, $value);
fwrite($bytes_io, pack("@".(-$l % 4))); fwrite($bytes_io, pack('@'.(-$l % 4)));
} }
} }
} }
/** /**
* :type bytes_io: io.BytesIO object * :type bytes_io: io.BytesIO object.
*/ */
function deserialize(&$bytes_io, $type_ = null, $subtype = null) { public function deserialize(&$bytes_io, $type_ = null, $subtype = null)
{
assert(get_resource_type($bytes_io) == 'file' || get_resource_type($bytes_io) == 'stream'); assert(get_resource_type($bytes_io) == 'file' || get_resource_type($bytes_io) == 'stream');
if (($type_ == 'int')) { if (($type_ == 'int')) {
$x = $this->struct->unpack('<i', fread($bytes_io, 4)) [0]; $x = $this->struct->unpack('<i', fread($bytes_io, 4)) [0];
@ -174,6 +189,7 @@ class TL {
} }
} }
} }
return $x; return $x;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
$__all__ = ['Chat', 'User', 'Message', 'Contact']; $__all__ = ['Chat', 'User', 'Message', 'Contact'];

View File

@ -1,11 +1,16 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
class Chat { class chat
function __construct() { {
public function __construct()
{
$this->_users = []; $this->_users = [];
} }
function add_user($user) {
public function add_user($user)
{
$this->_users += $user; $this->_users += $user;
} }
} }

View File

@ -1,5 +1,7 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
class Contact { class contact
{
} }

View File

@ -1,43 +1,51 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
require_once ('os.php'); require_once 'os.php';
class File { class file
function __construct($path) { {
public function __construct($path)
{
$this->_path = $path; $this->_path = $path;
} }
/** /**
* truncates the file and create new with :param bytes. * truncates the file and create new with :param bytes.
* :return number of bytes written * :return number of bytes written.
*/ */
function write_bytes($bytes) { public function write_bytes($bytes)
{
// py2php.fixme "with" unsupported. // py2php.fixme "with" unsupported.
} }
/** /**
* read the file as bytes. :return b'' on file not exist * read the file as bytes. :return b'' on file not exist.
*/ */
function read_bytes() { public function read_bytes()
{
if (!(new exists($this->_path))) { if (!(new exists($this->_path))) {
return ''; return '';
} }
// py2php.fixme "with" unsupported. // py2php.fixme "with" unsupported.
} }
/** /**
* tries to open with os default viewer * tries to open with os default viewer.
*/ */
function open() { public function open()
{
new call((os::name == 'nt') ? 'cmd /c start "" "'.$this->_path.'"' : [platform::startswith('darwin') ? 'open' : 'xdg-open', $this->_path]); new call((os::name == 'nt') ? 'cmd /c start "" "'.$this->_path.'"' : [platform::startswith('darwin') ? 'open' : 'xdg-open', $this->_path]);
} }
/** /**
* try to remove the file * try to remove the file.
*/ */
function remove() { public function remove()
{
try { try {
os::remove($this->_path); os::remove($this->_path);
} } catch (FileNotFoundError $e) {
catch(FileNotFoundError $e) {
} }
} }
} }

View File

@ -1,6 +1,8 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
require_once ('crypt.php'); require_once 'crypt.php';
class Message { class message
{
} }

View File

@ -1,280 +1,373 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
require_once ('os.php'); require_once 'os.php';
class TelepyShell { class TelepyShell
{
public $intro = 'Welcome to telepy interactive shell. Type help or ? for help. public $intro = 'Welcome to telepy interactive shell. Type help or ? for help.
'; ';
public $prompt = '>'; public $prompt = '>';
function preloop() {
require_once ('classes/telepy.php'); public function preloop()
{
require_once 'classes/telepy.php';
$this->_telepy = new Telepy(); $this->_telepy = new Telepy();
} }
function precmd($line) {
public function precmd($line)
{
$line = $line->lstrip(); $line = $line->lstrip();
$blank_pos = $line->find(' '); $blank_pos = $line->find(' ');
if (($blank_pos < 0)) { if (($blank_pos < 0)) {
return $line->lower(); return $line->lower();
} }
return array_slice($line, null, $blank_pos)->lower().' '.array_slice($line, ($blank_pos + 1), null); return array_slice($line, null, $blank_pos)->lower().' '.array_slice($line, ($blank_pos + 1), null);
} }
function completedefault(...$ignored) {
public function completedefault(...$ignored)
{
pyjslib_printnl($ignored); pyjslib_printnl($ignored);
} }
function complete($text, $state) {
public function complete($text, $state)
{
$this->super()->complete($text, $state); $this->super()->complete($text, $state);
pyjslib_printnl('completing'); pyjslib_printnl('completing');
} }
/** /**
* shell <command-line> * shell <command-line>
* lets you use external shell. !<command-line> for short-hand. * lets you use external shell. !<command-line> for short-hand.
*/ */
function do_shell($line) { public function do_shell($line)
{
pyjslib_printnl(os::popen($line)->read()); pyjslib_printnl(os::popen($line)->read());
} }
/** /**
* msg <peer> * msg <peer>
* sends message to this peer * sends message to this peer.
*/ */
function do_msg($arg) { public function do_msg($arg)
{
} }
/** /**
* fwd <user> <msg-no> * fwd <user> <msg-no>
* forward message to user. You can see message numbers starting client with -N * forward message to user. You can see message numbers starting client with -N.
*/ */
function do_fwd($arg) { public function do_fwd($arg)
{
} }
/** /**
* chat_with_peer <peer> * chat_with_peer <peer>
* starts one on one chat session with this peer. /exit or /quit to end this mode. * starts one on one chat session with this peer. /exit or /quit to end this mode.
*/ */
function do_chat_with_peer($arg) { public function do_chat_with_peer($arg)
{
} }
/** /**
* add_contact <phone-number> <first-name> <last-name> * add_contact <phone-number> <first-name> <last-name>
* tries to add contact to contact-list by phone * tries to add contact to contact-list by phone.
*/ */
function do_add_contact($arg) { public function do_add_contact($arg)
{
} }
/** /**
* rename_contact <user> <first-name> <last-name> * rename_contact <user> <first-name> <last-name>
* tries to rename contact. If you have another device it will be a fight * tries to rename contact. If you have another device it will be a fight.
*/ */
function do_rename_contact($arg) { public function do_rename_contact($arg)
{
} }
/** /**
* mark_read <peer> * mark_read <peer>
* mark read all received messages with peer * mark read all received messages with peer.
*/ */
function do_mark_read($arg) { public function do_mark_read($arg)
{
} }
/** /**
* delete_msg <msg-no> * delete_msg <msg-no>
* deletes message (not completly, though) * deletes message (not completly, though).
*/ */
function do_delete_msg($arg) { public function do_delete_msg($arg)
{
} }
/** /**
* restore_msg <msg-no> * restore_msg <msg-no>
* restores delete message. Impossible for secret chats. Only possible short time (one hour, I think) after deletion * restores delete message. Impossible for secret chats. Only possible short time (one hour, I think) after deletion.
*/ */
function do_restore_msg($arg) { public function do_restore_msg($arg)
{
} }
/** /**
* send_photo <peer> <photo-file-name> * send_photo <peer> <photo-file-name>
* sends photo to peer * sends photo to peer.
*/ */
function do_send_photo($arg) { public function do_send_photo($arg)
{
} }
/** /**
* send_video <peer> <video-file-name> * send_video <peer> <video-file-name>
* sends video to peer * sends video to peer.
*/ */
function do_send_video($arg) { public function do_send_video($arg)
{
} }
/** /**
* send_text <peer> <text-file-name> * send_text <peer> <text-file-name>
* sends text file as plain messages * sends text file as plain messages.
*/ */
function do_send_text($arg) { public function do_send_text($arg)
{
} }
/** /**
* load_photo <msg-no> * load_photo <msg-no>
* loads photo to download dir * loads photo to download dir.
*/ */
function do_load_photo($arg) { public function do_load_photo($arg)
{
} }
/** /**
* load_video <msg-no> * load_video <msg-no>
* loads video to download dir * loads video to download dir.
*/ */
function do_load_video($arg) { public function do_load_video($arg)
{
} }
/** /**
* load_video_thumb <msg-no> * load_video_thumb <msg-no>
* loads video thumbnail to download dir * loads video thumbnail to download dir.
*/ */
function do_load_video_thumb($arg) { public function do_load_video_thumb($arg)
{
} }
/** /**
* load_audio <msg-no> * load_audio <msg-no>
* loads audio to download dir * loads audio to download dir.
*/ */
function do_load_audio($arg) { public function do_load_audio($arg)
{
} }
/** /**
* load_document <msg-no> * load_document <msg-no>
* loads document to download dir * loads document to download dir.
*/ */
function do_load_document($arg) { public function do_load_document($arg)
{
} }
/** /**
* load_document_thumb <msg-no> * load_document_thumb <msg-no>
* loads document thumbnail to download dir * loads document thumbnail to download dir.
*/ */
function do_load_document_thumb($arg) { public function do_load_document_thumb($arg)
{
} }
/** /**
* view_photo <msg-no> * view_photo <msg-no>
* loads photo/video to download dir and starts system default viewer * loads photo/video to download dir and starts system default viewer.
*/ */
function do_view_photo($arg) { public function do_view_photo($arg)
{
} }
/** /**
* view_video <msg-no> * view_video <msg-no>.
*/ */
function do_view_video($arg) { public function do_view_video($arg)
{
} }
/** /**
* view_video_thumb <msg-no> * view_video_thumb <msg-no>.
*/ */
function do_view_video_thumb($arg) { public function do_view_video_thumb($arg)
{
} }
/** /**
* view_audio <msg-no> * view_audio <msg-no>.
*/ */
function do_view_audio($arg) { public function do_view_audio($arg)
{
} }
/** /**
* view_document <msg-no> * view_document <msg-no>.
*/ */
function do_view_document($arg) { public function do_view_document($arg)
{
} }
/** /**
* view_document_thumb <msg-no> * view_document_thumb <msg-no>.
*/ */
function do_view_document_thumb($arg) { public function do_view_document_thumb($arg)
{
} }
/** /**
* fwd_media <msg-no> * fwd_media <msg-no>
* send media in your message. Use this to prevent sharing info about author of media (though, it is possible to determine user_id from media itself, it is not possible get access_hash of this user) * send media in your message. Use this to prevent sharing info about author of media (though, it is possible to determine user_id from media itself, it is not possible get access_hash of this user).
*/ */
function do_fwd_media($arg) { public function do_fwd_media($arg)
{
} }
/** /**
* set_profile_photo <photo-file-name> * set_profile_photo <photo-file-name>
* sets userpic. Photo should be square, or server will cut biggest central square part * sets userpic. Photo should be square, or server will cut biggest central square part.
*/ */
function do_set_profile_photo($arg) { public function do_set_profile_photo($arg)
{
} }
/** /**
* chat_info <chat> * chat_info <chat>
* prints info about chat * prints info about chat.
*/ */
function do_chat_info($arg) { public function do_chat_info($arg)
{
$arg = $arg->split(); $arg = $arg->split();
if ((count($arg) == 1)) { if ((count($arg) == 1)) {
pyjslib_printnl(['chat_info called with ', $arg[0]]); pyjslib_printnl(['chat_info called with ', $arg[0]]);
} }
} }
/** /**
* chat_add_user <chat> <user> * chat_add_user <chat> <user>
* add user to chat * add user to chat.
*/ */
function do_chat_add_user($arg) { public function do_chat_add_user($arg)
{
pyjslib_printnl($arg); pyjslib_printnl($arg);
} }
/** /**
* chat_del_user <chat> <user> * chat_del_user <chat> <user>
* remove user from chat * remove user from chat.
*/ */
function do_chat_del_user($arg) { public function do_chat_del_user($arg)
{
} }
/** /**
* chat_rename <chat> <new-name> * chat_rename <chat> <new-name>
* rename chat room * rename chat room.
*/ */
function do_chat_rename($arg) { public function do_chat_rename($arg)
{
$arg = $arg->split(); $arg = $arg->split();
} }
/** /**
* create_group_chat <chat topic> <user1> <user2> <user3> ... * create_group_chat <chat topic> <user1> <user2> <user3> ...
* creates a groupchat with users, use chat_add_user to add more users * creates a groupchat with users, use chat_add_user to add more users.
*/ */
function do_create_group_chat($chat_topic, $user1, $user2, $user3) { public function do_create_group_chat($chat_topic, $user1, $user2, $user3)
{
pyjslib_printnl($chat_topic); pyjslib_printnl($chat_topic);
pyjslib_printnl([$user1, $user2, $user3]); pyjslib_printnl([$user1, $user2, $user3]);
} }
/** /**
* chat_set_photo <chat> <photo-file-name> * chat_set_photo <chat> <photo-file-name>
* sets group chat photo. Same limits as for profile photos. * sets group chat photo. Same limits as for profile photos.
*/ */
function do_chat_set_photo($chat, $photo) { public function do_chat_set_photo($chat, $photo)
{
} }
/** /**
* search <peer> <pattern> * search <peer> <pattern>
* searches pattern in messages with peer * searches pattern in messages with peer.
*/ */
function do_search($pattern) { public function do_search($pattern)
{
} }
/** /**
* global_search <pattern> * global_search <pattern>
* searches pattern in all messages * searches pattern in all messages.
*/ */
function do_global_search($pattern) { public function do_global_search($pattern)
{
} }
/** /**
* create_secret_chat <user> * create_secret_chat <user>
* creates secret chat with this user * creates secret chat with this user.
*/ */
function do_create_secret_chat($user) { public function do_create_secret_chat($user)
{
} }
/** /**
* visualize_key <secret_chat> * visualize_key <secret_chat>
* prints visualization of encryption key. You should compare it to your partner's one * prints visualization of encryption key. You should compare it to your partner's one.
*/ */
function do_visualize_key($secret_chat) { public function do_visualize_key($secret_chat)
{
} }
/** /**
* set_ttl <secret_chat> <ttl> * set_ttl <secret_chat> <ttl>
* sets ttl to secret chat. Though client does ignore it, client on other end can make use of it * sets ttl to secret chat. Though client does ignore it, client on other end can make use of it.
*/ */
function do_set_ttl($secret_chat, $ttl) { public function do_set_ttl($secret_chat, $ttl)
{
} }
/** /**
* accept_secret_chat <secret_chat> * accept_secret_chat <secret_chat>
* manually accept secret chat (only useful when starting with -E key) * manually accept secret chat (only useful when starting with -E key).
*/ */
function do_accept_secret_chat($secret_chat) { public function do_accept_secret_chat($secret_chat)
{
} }
/** /**
* user_info <user> * user_info <user>
* prints info about user * prints info about user.
*/ */
function do_user_info($user) { public function do_user_info($user)
{
} }
/** /**
* history <peer> [limit] * history <peer> [limit]
* prints history (and marks it as read). Default limit = 40 * prints history (and marks it as read). Default limit = 40.
*/ */
function do_history($peer, $limit = 40) { public function do_history($peer, $limit = 40)
{
if (($peer == '')) { if (($peer == '')) {
pyjslib_printnl('no peer have specified'); pyjslib_printnl('no peer have specified');
return; return;
} }
$args = $peer->split(); $args = $peer->split();
if (!in_array(count($args), [1, 2])) { if (!in_array(count($args), [1, 2])) {
pyjslib_printnl(['not appropriate number of arguments : ', $peer]); pyjslib_printnl(['not appropriate number of arguments : ', $peer]);
return; return;
} }
if ((count($args) == 2)) { if ((count($args) == 2)) {
@ -286,54 +379,70 @@ class TelepyShell {
pyjslib_printnl($peer); pyjslib_printnl($peer);
pyjslib_printnl($limit); pyjslib_printnl($limit);
} }
/** /**
* dialog_list * dialog_list
* prints info about your dialogs * prints info about your dialogs.
*/ */
function do_dialog_list($ignored) { public function do_dialog_list($ignored)
{
} }
/** /**
* contact_list * contact_list
* prints info about users in your contact list * prints info about users in your contact list.
*/ */
function do_contact_list($ignored) { public function do_contact_list($ignored)
{
} }
/** /**
* suggested_contacts * suggested_contacts
* print info about contacts, you have max common friends * print info about contacts, you have max common friends.
*/ */
function do_suggested_contacts($ignored) { public function do_suggested_contacts($ignored)
{
} }
/** /**
* stats * stats
* just for debugging * just for debugging.
*/ */
function do_stats($ignored) { public function do_stats($ignored)
{
} }
/** /**
* export_card * export_card
* print your 'card' that anyone can later use to import your contact * print your 'card' that anyone can later use to import your contact.
*/ */
function do_export_card($card) { public function do_export_card($card)
{
} }
/** /**
* import_card <card> * import_card <card>
* gets user by card. You can write messages to him after that. * gets user by card. You can write messages to him after that.
*/ */
function do_import_card($card) { public function do_import_card($card)
{
} }
/** /**
* quit_force * quit_force
* quit without waiting for query ends * quit without waiting for query ends.
*/ */
function do_quit_force($ignored) { public function do_quit_force($ignored)
{
return true; return true;
} }
/** /**
* quit * quit
* wait for all queries to end then quit * wait for all queries to end then quit.
*/ */
function do_quit($ignored) { public function do_quit($ignored)
{
return true; return true;
} }
} }

View File

@ -1,15 +1,17 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
class Telepy { class telepy
function __construct() { {
public function __construct()
{
try { try {
require_once ('configparser.php'); require_once 'configparser.php';
} catch (ImportError $e) {
require_once 'ConfigParser.php';
} }
catch(ImportError $e) { require_once 'mtproto.php';
require_once ('ConfigParser.php');
}
require_once ('mtproto.php');
$this->_config = $configparser->ConfigParser(); $this->_config = $configparser->ConfigParser();
if (!($this->_config->read('credentials'))) { if (!($this->_config->read('credentials'))) {
pyjslib_printnl('File \'credentials\' seems to not exist.'); pyjslib_printnl('File \'credentials\' seems to not exist.');
@ -19,7 +21,7 @@ class Telepy {
$port = $this->_config->getint('App data', 'port'); $port = $this->_config->getint('App data', 'port');
$this->_session = $mtproto->Session($ip, $port); $this->_session = $mtproto->Session($ip, $port);
$this->_session->create_auth_key(); $this->_session->create_auth_key();
$__temp22 = py2php_kwargs_method_call($this->_session, 'method_call', ['get_future_salts'], ["num" => 3]); $__temp22 = py2php_kwargs_method_call($this->_session, 'method_call', ['get_future_salts'], ['num' => 3]);
$this->_salt = $__temp22; $this->_salt = $__temp22;
$future_salts = $__temp22; $future_salts = $__temp22;
} }

View File

@ -1,12 +1,16 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
class User { class user
{
public $me = null; public $me = null;
// current connected user // current connected user
public $friends = []; public $friends = [];
// current connected user's friends // current connected user's friends
function __construct($uid) { public function __construct($uid)
{
$this->uid = $uid; $this->uid = $uid;
} }
} }

View File

@ -1,14 +1,20 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
require_once ('AES.class.php'); require_once 'AES.class.php';
class crypt { class crypt
function ige_encrypt($message, $key, $iv) { {
public function ige_encrypt($message, $key, $iv)
{
return _ige($message, $key, $iv, 'encrypt'); return _ige($message, $key, $iv, 'encrypt');
} }
function ige_decrypt($message, $key, $iv) {
public function ige_decrypt($message, $key, $iv)
{
return _ige($message, $key, $iv, 'decrypt'); return _ige($message, $key, $iv, 'decrypt');
} }
/** /**
* Given a key, given an iv, and message * Given a key, given an iv, and message
* do whatever operation asked in the operation field. * do whatever operation asked in the operation field.
@ -17,9 +23,10 @@ class crypt {
* message must be a multiple by 16 bytes (for division in 16 byte blocks) * message must be a multiple by 16 bytes (for division in 16 byte blocks)
* key must be 32 byte * key must be 32 byte
* iv must be 32 byte (it's not internally used in AES 256 ECB, but it's * iv must be 32 byte (it's not internally used in AES 256 ECB, but it's
* needed for IGE) * needed for IGE).
*/ */
function _ige($message, $key, $iv, $operation = 'decrypt') { public function _ige($message, $key, $iv, $operation = 'decrypt')
{
$message = str_split($message); $message = str_split($message);
if ((len($key) != 32)) { if ((len($key) != 32)) {
throw new Exception('key must be 32 bytes long (was '.len($key).' bytes)'); throw new Exception('key must be 32 bytes long (was '.len($key).' bytes)');
@ -55,6 +62,7 @@ class crypt {
} }
$ciphered .= $outdata; $ciphered .= $outdata;
} }
return $ciphered; return $ciphered;
} }
} }

View File

@ -1,21 +1,21 @@
<?php <?php
# Copyright 2006 James Tauber and contributors // Copyright 2006 James Tauber and contributors
# //
# Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
# You may obtain a copy of the License at // You may obtain a copy of the License at
# //
# http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
# //
# Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
# limitations under the License. // limitations under the License.
/** /**
* This call makes three things happen: * This call makes three things happen:.
* *
* 1) a global error handler for php errors that causes an exception to be * 1) a global error handler for php errors that causes an exception to be
* thrown instead of standard php error handling. * thrown instead of standard php error handling.
@ -26,74 +26,68 @@
* 3) error_reporting is set to E_STRICT, so that even notices cause an * 3) error_reporting is set to E_STRICT, so that even notices cause an
* exception to be thrown. This way we are forced to deal with even * exception to be thrown. This way we are forced to deal with even
* the minor issues during development, and hopefully fewer issues * the minor issues during development, and hopefully fewer issues
make it out into the world.
*/ */
require_once( dirname(__FILE__) . DIRECTORY_SEPARATOR . 'strict_mode.php' ); require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'strict_mode.php';
init_strict_mode(); init_strict_mode();
# iteration from Bob Ippolito's Iteration in JavaScript // iteration from Bob Ippolito's Iteration in JavaScript
# pyjs_extend from Kevin Lindsey's Inteheritance Tutorial (http://www.kevlindev.com/tutorials/javascript/inheritance/) // pyjs_extend from Kevin Lindsey's Inteheritance Tutorial (http://www.kevlindev.com/tutorials/javascript/inheritance/)
# type functions from Douglas Crockford's Remedial Javascript: http://www.crockford.com/javascript/remedial.html
function pyjslib_isObject($a) {
// type functions from Douglas Crockford's Remedial Javascript: http://www.crockford.com/javascript/remedial.html
function pyjslib_isObject($a)
{
return is_object($a); return is_object($a);
} }
function pyjslib_isFunction($a) { function pyjslib_isFunction($a)
{
return is_function($a); return is_function($a);
} }
function pyjslib_isString($a) { function pyjslib_isString($a)
{
return is_string($a); return is_string($a);
} }
function pyjslib_isNull($a) { function pyjslib_isNull($a)
{
return is_null($a); return is_null($a);
} }
function pyjslib_isArray($a) { function pyjslib_isArray($a)
{
return is_array($a); return is_array($a);
} }
function pyjslib_isUndefined($a) { function pyjslib_isUndefined($a)
{
return !isset($a); return !isset($a);
} }
function pyjslib_isIteratable($a) { function pyjslib_isIteratable($a)
{
return $a instanceof Traversable; return $a instanceof Traversable;
} }
function pyjslib_isNumber($a) { function pyjslib_isNumber($a)
{
return is_numeric($a); return is_numeric($a);
} }
function pyjslib_int($a) { function pyjslib_int($a)
{
return (int) $a; return (int) $a;
} }
function pyjslib_str($val) { function pyjslib_str($val)
{
return (string) $val; return (string) $val;
} }
function pyjslib_del_slice(&$list, $from, $to, $step=1) { function pyjslib_del_slice(&$list, $from, $to, $step = 1)
{
if ($from <= 0) { if ($from <= 0) {
$from = 0; $from = 0;
} }
@ -108,7 +102,8 @@ function pyjslib_del_slice(&$list, $from, $to, $step=1) {
} }
} }
function pyjslib_array_slice($list, $from, $to, $step=1) { function pyjslib_array_slice($list, $from, $to, $step = 1)
{
$newlist = []; $newlist = [];
if ($from <= 0) { if ($from <= 0) {
$from = 0; $from = 0;
@ -122,12 +117,14 @@ function pyjslib_array_slice($list, $from, $to, $step=1) {
for ($i = $from; $i < $to; $i += $step) { for ($i = $from; $i < $to; $i += $step) {
$newlist[] = $list[$i]; $newlist[] = $list[$i];
} }
return $newlist; return $newlist;
} }
# taken from mochikit: range( [start,] stop[, step] ) // taken from mochikit: range( [start,] stop[, step] )
function pyjslib_range($start, $stop = null, $step = 1) { function pyjslib_range($start, $stop = null, $step = 1)
{
if ($stop === null) { if ($stop === null) {
$stop = $start; $stop = $start;
$start = 0; $start = 0;
@ -135,29 +132,35 @@ function pyjslib_range($start, $stop = null, $step = 1) {
if ($stop <= $start && $step < 0) { if ($stop <= $start && $step < 0) {
$arr = range($stop, $start, -$step); $arr = range($stop, $start, -$step);
array_pop($arr); array_pop($arr);
return array_reverse($arr, false); return array_reverse($arr, false);
} }
$arr = range($start, $stop, $step); $arr = range($start, $stop, $step);
array_pop($arr); array_pop($arr);
return $arr; return $arr;
} }
function pyjslib_filter($callback, $iterable) { function pyjslib_filter($callback, $iterable)
{
$a = []; $a = [];
foreach ($iterable as $item) { foreach ($iterable as $item) {
if (call_user_func($callback, $item)) { if (call_user_func($callback, $item)) {
$a[] = $item; $a[] = $item;
} }
} }
return $a; return $a;
} }
function pyjslib_globals() { function pyjslib_globals()
{
return $GLOBALS; return $GLOBALS;
} }
function pyjslib_map($callable) { function pyjslib_map($callable)
{
$done = false; $done = false;
$call_cnt = 0; $call_cnt = 0;
$results = []; $results = [];
@ -180,21 +183,25 @@ function pyjslib_map($callable) {
$results[] = call_user_func_array($callable, $func_args); $results[] = call_user_func_array($callable, $func_args);
$call_cnt++; $call_cnt++;
} }
return $results; return $results;
} }
function pyjslib_zip() { function pyjslib_zip()
{
$params = func_get_args(); $params = func_get_args();
if (count($params) === 1) { // this case could be probably cleaner if (count($params) === 1) { // this case could be probably cleaner
// single iterable passed // single iterable passed
$result = array(); $result = [];
foreach ($params[0] as $item) { foreach ($params[0] as $item) {
$result[] = array($item); $result[] = [$item];
}; }
return $result; return $result;
}; }
$result = call_user_func_array('array_map',array_merge(array(null),$params)); $result = call_user_func_array('array_map', array_merge([null], $params));
$length = min(array_map('count', $params)); $length = min(array_map('count', $params));
return array_slice($result, 0, $length); return array_slice($result, 0, $length);
} }
@ -203,7 +210,8 @@ function pyjslib_is_assoc($arr)
return array_keys($arr) !== range(0, count($arr) - 1); return array_keys($arr) !== range(0, count($arr) - 1);
} }
function pyjslib_dict($arg=null) { function pyjslib_dict($arg = null)
{
if ($arg === null) { if ($arg === null) {
return []; return [];
} }
@ -216,33 +224,30 @@ function pyjslib_dict($arg=null) {
$dict[$a[0]] = $a[1]; $dict[$a[0]] = $a[1];
} }
} }
return $dict; return $dict;
} }
function pyjslib_printWorker($objs, $nl, $multi_arg, $depth=1) { function pyjslib_printWorker($objs, $nl, $multi_arg, $depth = 1)
{
$buf = ''; $buf = '';
if (is_array($objs) && $multi_arg && $depth == 1) { if (is_array($objs) && $multi_arg && $depth == 1) {
$cnt = 0; $cnt = 0;
foreach ($objs as $obj) { foreach ($objs as $obj) {
if ($cnt++ > 0) { if ($cnt++ > 0) {
$buf .= " "; $buf .= ' ';
} }
$buf .= pyjslib_printWorker($obj, $nl, $multi_arg, $depth + 1); $buf .= pyjslib_printWorker($obj, $nl, $multi_arg, $depth + 1);
} }
} } elseif (is_bool($objs)) {
else if( is_bool( $objs )) { $buf = $objs ? 'True' : 'False';
$buf = $objs ? "True" : "False"; } elseif (is_null($objs)) {
}
else if( is_null( $objs )) {
$buf = 'None'; $buf = 'None';
} } elseif (is_float($objs)) {
else if( is_float( $objs )) {
$buf = (int) $objs; $buf = (int) $objs;
} } elseif (is_string($objs) && ($multi_arg && $depth > 2 || (!$multi_arg && $depth > 1))) {
else if( is_string( $objs ) && ($multi_arg && $depth > 2 || (!$multi_arg && $depth > 1) ) ) {
$buf = "'$objs'"; $buf = "'$objs'";
} } elseif (is_array($objs)) {
elseif( is_array( $objs )) {
$buf = '['; $buf = '[';
$cnt = 0; $cnt = 0;
foreach ($objs as $obj) { foreach ($objs as $obj) {
@ -252,32 +257,35 @@ function pyjslib_printWorker($objs, $nl, $multi_arg, $depth=1) {
} }
$buf .= $val; $buf .= $val;
} }
$buf .= "]"; $buf .= ']';
// $buf = '[' . implode( ", ", $objs ) . ']'; // $buf = '[' . implode( ", ", $objs ) . ']';
} } else {
else {
$buf = $objs; $buf = $objs;
} }
if ($depth == 1 && (!strlen($buf) || $buf[strlen($buf) - 1] != "\n")) { if ($depth == 1 && (!strlen($buf) || $buf[strlen($buf) - 1] != "\n")) {
$buf .= $nl ? "\n" : " "; $buf .= $nl ? "\n" : ' ';
} }
return $buf; return $buf;
} }
function pyjslib_repr($obj) { function pyjslib_repr($obj)
{
return pyjslib_printWorker($obj, false, false); return pyjslib_printWorker($obj, false, false);
} }
function pyjslib_print($objs, $multi_arg=false) { function pyjslib_print($objs, $multi_arg = false)
{
echo pyjslib_printWorker($objs, false, $multi_arg); echo pyjslib_printWorker($objs, false, $multi_arg);
} }
function pyjslib_printnl($objs, $multi_arg=false) { function pyjslib_printnl($objs, $multi_arg = false)
{
echo pyjslib_printWorker($objs, true, $multi_arg); echo pyjslib_printWorker($objs, true, $multi_arg);
} }
function py2php_kwargs_function_call($funcname, $ordered, $named) { function py2php_kwargs_function_call($funcname, $ordered, $named)
{
if ($funcname == 'array' || $funcname == 'pyjslib_dict') { if ($funcname == 'array' || $funcname == 'pyjslib_dict') {
return $named; return $named;
} }
@ -304,8 +312,8 @@ function py2php_kwargs_function_call($funcname, $ordered, $named) {
return call_user_func_array($funcname, $ordered); return call_user_func_array($funcname, $ordered);
} }
function py2php_kwargs_method_call( $obj, $method, $ordered, $named ) { function py2php_kwargs_method_call($obj, $method, $ordered, $named)
{
$num_ordered = count($ordered); $num_ordered = count($ordered);
$count = 1; $count = 1;
@ -322,22 +330,26 @@ function py2php_kwargs_method_call( $obj, $method, $ordered, $named ) {
} }
$callable = [$obj, $method]; $callable = [$obj, $method];
return call_user_func_array($callable, $ordered); return call_user_func_array($callable, $ordered);
} }
class IOError extends Exception{ class IOError extends Exception
{
} }
class ValueError extends Exception{ class ValueError extends Exception
{
} }
function pyjslib_open( $name, $mode="r", $buffering=null ) { function pyjslib_open($name, $mode = 'r', $buffering = null)
{
return new pyjslib_file($name, $mode, $buffering); return new pyjslib_file($name, $mode, $buffering);
} }
class pyjslib_file implements Iterator { class pyjslib_file implements Iterator
{
private $fh = false; private $fh = false;
private $current_line = null; private $current_line = null;
@ -349,12 +361,14 @@ class pyjslib_file implements Iterator {
public $newlines = null; public $newlines = null;
public $softspace = false; public $softspace = false;
function __construct($name_or_fd, $mode="r", $buffering=null) { public function __construct($name_or_fd, $mode = 'r', $buffering = null)
{
if (is_resource($name_or_fd)) { if (is_resource($name_or_fd)) {
$this->fh = $name_or_fd; $this->fh = $name_or_fd;
$this->closed = false; $this->closed = false;
$meta = stream_get_meta_data($name_or_df); $meta = stream_get_meta_data($name_or_df);
$this->mode = $meta['mode']; $this->mode = $meta['mode'];
return; return;
} }
$name = $name_or_fd; $name = $name_or_fd;
@ -365,15 +379,13 @@ class pyjslib_file implements Iterator {
} }
$this->closed = false; $this->closed = false;
$this->mode = $mode; $this->mode = $mode;
} } catch (Exception $e) {
catch( Exception $e ) {
throw new IOError($e->getMessage(), $e->getCode()); throw new IOError($e->getMessage(), $e->getCode());
} }
} }
public function close()
{
function close() {
if ($this->fh) { if ($this->fh) {
fclose($this->fh); fclose($this->fh);
$this->fh = null; $this->fh = null;
@ -381,24 +393,29 @@ class pyjslib_file implements Iterator {
} }
} }
function flush() { public function flush()
{
if (!$this->fh) { if (!$this->fh) {
throw new ValueError("File is closed."); throw new ValueError('File is closed.');
} }
fflush($this->fh); fflush($this->fh);
} }
function fileno() { public function fileno()
{
if (!$this->fh) { if (!$this->fh) {
throw new ValueError("File is closed."); throw new ValueError('File is closed.');
} }
return $this->fh; return $this->fh;
} }
function isatty() { public function isatty()
{
if (!$this->fh) { if (!$this->fh) {
throw new ValueError("File is closed."); throw new ValueError('File is closed.');
} }
return posix_isatty($this->fh); return posix_isatty($this->fh);
} }
@ -406,51 +423,63 @@ class pyjslib_file implements Iterator {
* Begin PHP Iterator implementation * Begin PHP Iterator implementation
* --- * ---
*/ */
function rewind() { public function rewind()
{
fseek($this->fh, 0); fseek($this->fh, 0);
$this->line = 0; $this->line = 0;
} }
function current() { public function current()
{
if (!$this->current_line) { if (!$this->current_line) {
$this->current_line = fgets($this->fh); $this->current_line = fgets($this->fh);
} }
return $this->current_line; return $this->current_line;
} }
function key() { public function key()
{
return $this->line; return $this->line;
} }
function next() { public function next()
{
$this->current(); // ensure current line has been retrieved. $this->current(); // ensure current line has been retrieved.
$this->current_line = fgets($this->fh); $this->current_line = fgets($this->fh);
$this->line++; $this->line++;
return $this->current_line; return $this->current_line;
} }
function valid() { public function valid()
{
return $this->fh != false && !feof($this->fh); return $this->fh != false && !feof($this->fh);
} }
/* --- /* ---
* End PHP Iterator implementation * End PHP Iterator implementation
* --- * ---
*/ */
function read($size=null) { public function read($size = null)
{
if ($size !== null) { if ($size !== null) {
return fread($this->fh, $size); return fread($this->fh, $size);
} }
return stream_get_contents($this->fh); return stream_get_contents($this->fh);
} }
function readline($size=null) { public function readline($size = null)
{
return fgets($this->fh, $size); return fgets($this->fh, $size);
} }
function readlines($sizehint=null) { public function readlines($sizehint = null)
{
$len = 0; $len = 0;
$lines = array(); $lines = [];
while ($line = fgets($this->fh)) { while ($line = fgets($this->fh)) {
$len += strlen($line); $len += strlen($line);
$lines[] = $line; $lines[] = $line;
@ -458,29 +487,34 @@ class pyjslib_file implements Iterator {
break; break;
} }
} }
return $lines; return $lines;
} }
function seek($offset, $whence=SEEK_SET) { public function seek($offset, $whence = SEEK_SET)
{
return fseek($this->fh, $offset, $whence); return fseek($this->fh, $offset, $whence);
} }
function tell() { public function tell()
{
return ftell($this->fh); return ftell($this->fh);
} }
function truncate( $size ) { public function truncate($size)
{
$rc = ftruncate($this->fh, $size); $rc = ftruncate($this->fh, $size);
} }
function write( $str ) { public function write($str)
{
fwrite($this->fh, $str); fwrite($this->fh, $str);
} }
function writelines($sequence) { public function writelines($sequence)
{
foreach ($sequence as $line) { foreach ($sequence as $line) {
$this->write($line); $this->write($line);
} }
} }
} }

View File

@ -1,11 +1,12 @@
<?php <?php
class OSError extends Exception{ class OSError extends Exception
{
} }
class os { class os
{
const F_OK = 0x0001; const F_OK = 0x0001;
const R_OK = 0x0002; const R_OK = 0x0002;
const W_OK = 0x0004; const W_OK = 0x0004;
@ -47,221 +48,275 @@ class os {
public $environ; public $environ;
public $pathconf_names = []; public $pathconf_names = [];
static public function ctermid() { public static function ctermid()
{
return posix_ctermid(); return posix_ctermid();
} }
static public function getegid() { public static function getegid()
{
return posix_getegid(); return posix_getegid();
} }
static public function geteuid() { public static function geteuid()
{
return posix_geteuid(); return posix_geteuid();
} }
static public function getgid() { public static function getgid()
{
return posix_getgid(); return posix_getgid();
} }
static public function getgroups() { public static function getgroups()
{
return posix_getgroups(); return posix_getgroups();
} }
static public function initgroups($username, $gid) { public static function initgroups($username, $gid)
{
return posix_initgroups($username, $gid); return posix_initgroups($username, $gid);
} }
static public function getlogin() { public static function getlogin()
{
return posix_getlogin(); return posix_getlogin();
} }
static public function getpgid() { public static function getpgid()
{
return posix_getpgid(); return posix_getpgid();
} }
static public function getpgrp() { public static function getpgrp()
{
return posix_getpgrp(); return posix_getpgrp();
} }
static public function getpid() { public static function getpid()
{
return posix_getpid(); return posix_getpid();
} }
static public function getresuid() { public static function getresuid()
{
self::_unimplemented(); self::_unimplemented();
} }
static public function getresgid() { public static function getresgid()
{
self::_unimplemented(); self::_unimplemented();
} }
static public function getuid() { public static function getuid()
{
return posix_getuid(); return posix_getuid();
} }
static public function getenv($varname, $value=null) { public static function getenv($varname, $value = null)
{
return getenv($varname, $value); return getenv($varname, $value);
} }
static public function putenv($varname, $value) { public static function putenv($varname, $value)
{
putenv("$varname=$value"); putenv("$varname=$value");
} }
static public function setegid($egid) { public static function setegid($egid)
{
posix_setegid($egid); posix_setegid($egid);
} }
static public function seteuid($euid) { public static function seteuid($euid)
{
posix_seteuid($euid); posix_seteuid($euid);
} }
static public function setgid($gid) { public static function setgid($gid)
{
posix_setgid($gid); posix_setgid($gid);
} }
static public function setgroups($groups) { public static function setgroups($groups)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function setpgrp() { public static function setpgrp()
{
self::_unimplemented(); self::_unimplemented();
} }
static public function setpgid($pid, $pgrp) { public static function setpgid($pid, $pgrp)
{
posix_setpgid($pid, $pgrp); posix_setpgid($pid, $pgrp);
} }
static public function setregid($rgid, $egid) { public static function setregid($rgid, $egid)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function setresgid($rgid, $egid, $sgid) { public static function setresgid($rgid, $egid, $sgid)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function setresuid($ruid, $euid, $suid) { public static function setresuid($ruid, $euid, $suid)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function setreuid($ruid, $euid) { public static function setreuid($ruid, $euid)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function getsid($pid) { public static function getsid($pid)
{
return posix_getsid(); return posix_getsid();
} }
static public function setsid() { public static function setsid()
{
posix_setsid(); posix_setsid();
} }
static public function setuid($uid) { public static function setuid($uid)
{
posix_setuid($uid); posix_setuid($uid);
} }
static public function strerror($code) { public static function strerror($code)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function umask($mask) { public static function umask($mask)
{
umask($mask); umask($mask);
} }
static public function uname() { public static function uname()
{
return posix_uname(); return posix_uname();
} }
static public function unsetenv($varname) { public static function unsetenv($varname)
{
unset($_ENV[$varname]); unset($_ENV[$varname]);
} }
static public function fdopen($fd, $mode=null, $bufsize=null) { public static function fdopen($fd, $mode = null, $bufsize = null)
{
return new pyjslib_file($fd); return new pyjslib_file($fd);
} }
static public function popen($command, $mode=null, $bufsize=null) { public static function popen($command, $mode = null, $bufsize = null)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function tmpfile() { public static function tmpfile()
{
return tmpfile(); return tmpfile();
} }
static public function popen2($cmd, $mode=null, $bufsize=null) { public static function popen2($cmd, $mode = null, $bufsize = null)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function popen3($cmd, $mode=null, $bufsize=null) { public static function popen3($cmd, $mode = null, $bufsize = null)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function popen4($cmd, $mode=null, $bufsize=null) { public static function popen4($cmd, $mode = null, $bufsize = null)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function close($fd) { public static function close($fd)
{
fclose($fd); fclose($fd);
} }
static public function closerange($fd_low, $fd_high) { public static function closerange($fd_low, $fd_high)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function dup($fd) { public static function dup($fd)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function dup2($fd) { public static function dup2($fd)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function fchmod($fd, $mode) { public static function fchmod($fd, $mode)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function fchown($fd, $uid, $gid) { public static function fchown($fd, $uid, $gid)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function fdatasync($fd) { public static function fdatasync($fd)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function fpathconf($fd, $name) { public static function fpathconf($fd, $name)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function fstat($fd) { public static function fstat($fd)
{
$info = fstat($fd); $info = fstat($fd);
$obj = new stdClass; $obj = new stdClass();
foreach ($arr as $key => $v) { foreach ($arr as $key => $v) {
$attr = "st_" . $key; $attr = 'st_'.$key;
$obj->$attr = $v; $obj->$attr = $v;
} }
return $obj; return $obj;
} }
static public function fstatvfs($fd) { public static function fstatvfs($fd)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function fsync($fd) { public static function fsync($fd)
{
fsync($fd); fsync($fd);
} }
static public function ftruncate($fd, $length) { public static function ftruncate($fd, $length)
{
ftruncate($fd, $length); ftruncate($fd, $length);
} }
static public function isatty($fd) { public static function isatty($fd)
{
return posix_isatty($fd); return posix_isatty($fd);
} }
static public function lseek($fd, $pos, $how) { public static function lseek($fd, $pos, $how)
{
lseek($fd, $pos, $how); lseek($fd, $pos, $how);
} }
static public function open($file, $flags, $mode=0777) { public static function open($file, $flags, $mode = 0777)
{
// todo: define and map flag constants. See list at: // todo: define and map flag constants. See list at:
// https://docs.python.org/2/library/os.html#open-flag-constants // https://docs.python.org/2/library/os.html#open-flag-constants
@ -291,280 +346,338 @@ class os {
return fopen($file, $fl, false); return fopen($file, $fl, false);
} }
static public function pipe() { public static function pipe()
{
self::_unimplemented(); self::_unimplemented();
} }
static public function read($fd, $n) { public static function read($fd, $n)
{
return fread($fd, $n); return fread($fd, $n);
} }
static public function tcgetpgrp($fd) { public static function tcgetpgrp($fd)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function tcsetpgrp($fd, $pg) { public static function tcsetpgrp($fd, $pg)
{
self::_unimplemented(); self::_unimplemented();
} }
static public function ttyname($fd) { public static function ttyname($fd)
{
return posix_ttyname($fd); return posix_ttyname($fd);
} }
static public function write($fd, $str) { public static function write($fd, $str)
{
return fwrite($fd, $str); return fwrite($fd, $str);
} }
static function access($path, $mode) { public static function access($path, $mode)
{
return posix_access($path, $mode); return posix_access($path, $mode);
} }
static function chdir($path) { public static function chdir($path)
{
chdir($path); chdir($path);
} }
static function fchdir($path) { public static function fchdir($path)
{
fchdir($path); fchdir($path);
} }
static function getcwd() { public static function getcwd()
{
return getcwd(); return getcwd();
} }
static function getcwdu() { public static function getcwdu()
{
return getcwd(); return getcwd();
} }
static function chflags($path, $flags) { public static function chflags($path, $flags)
{
self::_unimplemented(); self::_unimplemented();
} }
static function chroot($path) { public static function chroot($path)
{
chroot($path); chroot($path);
} }
static function chmode($path, $mode) { public static function chmode($path, $mode)
{
self::_unimplemented(); self::_unimplemented();
} }
static function chown($path, $uid, $gid) { public static function chown($path, $uid, $gid)
{
chown($path, $uid, $gid); chown($path, $uid, $gid);
} }
static function lchflags($path, $flags) { public static function lchflags($path, $flags)
{
self::_unimplemented(); self::_unimplemented();
} }
static function lchmod($path, $mode) { public static function lchmod($path, $mode)
{
self::_unimplemented(); self::_unimplemented();
} }
static function lchown($path, $uid, $gid) { public static function lchown($path, $uid, $gid)
{
self::_unimplemented(); self::_unimplemented();
} }
static function link($source, $link_name) { public static function link($source, $link_name)
{
link($source, $link_name); link($source, $link_name);
} }
static function listdir($path) { public static function listdir($path)
{
self::_unimplemented(); self::_unimplemented();
} }
static function lstat($path) { public static function lstat($path)
{
self::_unimplemented(); self::_unimplemented();
} }
static function mkfifo($path, $mode=0666) { public static function mkfifo($path, $mode = 0666)
{
posix_mkfifo($path, $mode); posix_mkfifo($path, $mode);
} }
static function mknod($filename, $mode=0666, $device=0) { public static function mknod($filename, $mode = 0666, $device = 0)
{
return posix_mknod($filename, $mode); return posix_mknod($filename, $mode);
} }
static function major($path, $flags) { public static function major($path, $flags)
{
self::_unimplemented(); self::_unimplemented();
} }
static function minor($path, $flags) { public static function minor($path, $flags)
{
self::_unimplemented(); self::_unimplemented();
} }
static function makedev($major, $minor) { public static function makedev($major, $minor)
{
self::_unimplemented(); self::_unimplemented();
} }
static function mkdir($path, $mode=0777) { public static function mkdir($path, $mode = 0777)
{
mkdir($path, $mode, $recursive = false); mkdir($path, $mode, $recursive = false);
} }
static function makedirs($path, $mode=0777) { public static function makedirs($path, $mode = 0777)
{
mkdir($path, $mode, $recursive = true); mkdir($path, $mode, $recursive = true);
} }
static function pathconf($path, $name) { public static function pathconf($path, $name)
{
self::_unimplemented(); self::_unimplemented();
} }
static function readlink($path) { public static function readlink($path)
{
return readlink($path); return readlink($path);
} }
static function remove($path) { public static function remove($path)
{
if (!is_file($path)) { if (!is_file($path)) {
throw new OSError("Path is not a file. $path"); throw new OSError("Path is not a file. $path");
} }
try { try {
unlink($path); unlink($path);
} } catch (Exception $e) {
catch( Exception $e ) {
throw new OSError($e->getMessage(), $e->getCode()); throw new OSError($e->getMessage(), $e->getCode());
} }
} }
static function removedirs($path) { public static function removedirs($path)
{
self::_unimplemented(); self::_unimplemented();
} }
static function rename($src, $dst) { public static function rename($src, $dst)
{
if (is_dir($dst)) { if (is_dir($dst)) {
throw new OSError("Destination is a directory. $dst"); throw new OSError("Destination is a directory. $dst");
} }
rename($src, $dst); rename($src, $dst);
} }
static function renames($old, $new) { public static function renames($old, $new)
{
self::makedirs(dirname($new)); self::makedirs(dirname($new));
self::rename($old, $new); self::rename($old, $new);
} }
static function rmdir($path) { public static function rmdir($path)
{
rmdir($pat); rmdir($pat);
} }
static function stat($path) { public static function stat($path)
{
$arr = stat($path); $arr = stat($path);
if (!$arr) { if (!$arr) {
throw new OSError("Path does not exist. $path"); throw new OSError("Path does not exist. $path");
} }
$obj = new stdClass; $obj = new stdClass();
foreach ($arr as $key => $v) { foreach ($arr as $key => $v) {
$attr = "st_" . $key; $attr = 'st_'.$key;
$obj->$attr = $v; $obj->$attr = $v;
} }
return $obj; return $obj;
} }
static function stat_float_times($newvalue=null) { public static function stat_float_times($newvalue = null)
{
self::_unimplemented(); self::_unimplemented();
} }
static function statvfs() { public static function statvfs()
{
self::_unimplemented(); self::_unimplemented();
} }
static function symlink($source, $link_name) { public static function symlink($source, $link_name)
{
symlink($source, $link_name); symlink($source, $link_name);
} }
static function tempnam($dir=null, $prefix='') { public static function tempnam($dir = null, $prefix = '')
{
if (!$dir) { if (!$dir) {
$dir = sys_get_temp_dir(); $dir = sys_get_temp_dir();
} }
$name = tempnam($dir, $prefix); $name = tempnam($dir, $prefix);
unlink($name); unlink($name);
return $name; return $name;
} }
static function tmpnam() { public static function tmpnam()
{
return self::tempnam(); return self::tempnam();
} }
static function unlink($path) { public static function unlink($path)
{
unlink($path); unlink($path);
} }
static function utime($path, $times) { public static function utime($path, $times)
{
self::_unimplemented(); self::_unimplemented();
} }
static function walk($top, $topdown=true, $onerror=null, $followlinks=false) { public static function walk($top, $topdown = true, $onerror = null, $followlinks = false)
{
self::_unimplemented(); self::_unimplemented();
} }
/** /**
* Begin Process Management * Begin Process Management.
*/ */
public static function abort()
static function abort() { {
self::_unimplemented(); self::_unimplemented();
} }
static function execl($path, $arg0, $arg1) { public static function execl($path, $arg0, $arg1)
{
self::_unimplemented(); self::_unimplemented();
} }
static function execle($path, $arg0, $arg1, $env) { public static function execle($path, $arg0, $arg1, $env)
{
self::_unimplemented(); self::_unimplemented();
} }
static function execlp($file, $arg0, $arg1) { public static function execlp($file, $arg0, $arg1)
{
self::_unimplemented(); self::_unimplemented();
} }
static function execlpe($file, $arg0, $arg1, $env) { public static function execlpe($file, $arg0, $arg1, $env)
{
self::_unimplemented(); self::_unimplemented();
} }
static function execv($path, $args) { public static function execv($path, $args)
{
self::_unimplemented(); self::_unimplemented();
} }
static function execve($path, $args, $env) { public static function execve($path, $args, $env)
{
self::_unimplemented(); self::_unimplemented();
} }
static function execvp($file, $args) { public static function execvp($file, $args)
{
self::_unimplemented(); self::_unimplemented();
} }
static function execvpe($file, $args, $env) { public static function execvpe($file, $args, $env)
{
self::_unimplemented(); self::_unimplemented();
} }
static function _exit($n) { public static function _exit($n)
{
exit($n); exit($n);
} }
static function fork() { public static function fork()
{
return pcntl_fork(); return pcntl_fork();
} }
static function forkpty() { public static function forkpty()
{
self::_unimplemented(); self::_unimplemented();
} }
static function kill($pid, $sig) { public static function kill($pid, $sig)
{
posix_kill($pid, $sig); posix_kill($pid, $sig);
} }
static function killpg($pgid, $sig) { public static function killpg($pgid, $sig)
{
self::_unimplemented(); self::_unimplemented();
} }
static function nice($increment) { public static function nice($increment)
{
proc_nice($increment); proc_nice($increment);
} }
static function plock($op) { public static function plock($op)
{
self::_unimplemented(); self::_unimplemented();
} }
private static function _unimplemented()
{
private static function _unimplemented() { throw new Exception('Unimplemented. Please consider submitting a patch to py2php project on github.');
throw new Exception( "Unimplemented. Please consider submitting a patch to py2php project on github.");
} }
} }

View File

@ -1,24 +1,27 @@
<?php <?php
require_once(dirname(__FILE__) . '/os.php'); require_once dirname(__FILE__).'/os.php';
/** /**
* A class to emulate python's os.path * A class to emulate python's os.path.
*/ */
class os_path { class os_path
{
const supports_unicode_filenames = true; const supports_unicode_filenames = true;
static function abspath($path) { public static function abspath($path)
{
return self::normpath(self::join(getcwd(), $path)); return self::normpath(self::join(getcwd(), $path));
} }
static function basename($path) { public static function basename($path)
{
// is this right? // is this right?
return basename($path); return basename($path);
} }
static function commonprefix($list) { public static function commonprefix($list)
{
$pl = 0; // common prefix length $pl = 0; // common prefix length
$n = count($list); $n = count($list);
$l = strlen($list[0]); $l = strlen($list[0]);
@ -31,36 +34,44 @@ class os_path {
} }
$pl++; $pl++;
} }
return substr($list[0], 0, $pl); return substr($list[0], 0, $pl);
} }
static function dirname($path) { public static function dirname($path)
{
return dirname($path); return dirname($path);
} }
static function exists($path) { public static function exists($path)
{
return file_exists($path); return file_exists($path);
} }
static function lexists($path) { public static function lexists($path)
{
$rc = file_exists($path); $rc = file_exists($path);
if (!$rc && is_link($path)) { if (!$rc && is_link($path)) {
return true; return true;
} }
return $rc; return $rc;
} }
static function expanduser($path) { public static function expanduser($path)
{
if (strpos($path, '~') !== false) { if (strpos($path, '~') !== false) {
$info = posix_getpwuid(posix_getuid()); $info = posix_getpwuid(posix_getuid());
$path = str_replace('~', $info['dir'], $path); $path = str_replace('~', $info['dir'], $path);
} }
return $path; return $path;
} }
static function expandvars($path) { public static function expandvars($path)
{
$env = count($_ENV) ?: $_SERVER; $env = count($_ENV) ?: $_SERVER;
$map = array(); $map = [];
foreach ($env as $k => $v) { foreach ($env as $k => $v) {
if (!is_scalar($v)) { if (!is_scalar($v)) {
continue; continue;
@ -68,124 +79,148 @@ class os_path {
$map['$'.$k] = $v; $map['$'.$k] = $v;
$map['${'.$k.'}'] = $v; $map['${'.$k.'}'] = $v;
} }
return strtr($path, $map); return strtr($path, $map);
} }
static function getatime($path) { public static function getatime($path)
{
try { try {
$rc = fileatime($path); $rc = fileatime($path);
return $rc; return $rc;
} } catch (Exception $e) {
catch( Exception $e ) {
throw new OSError($e->getMessage, $e->getCode()); throw new OSError($e->getMessage, $e->getCode());
} }
} }
static function getmtime($path) { public static function getmtime($path)
{
try { try {
$rc = filemtime($path); $rc = filemtime($path);
return $rc; return $rc;
} } catch (Exception $e) {
catch( Exception $e ) {
throw new OSError($e->getMessage, $e->getCode()); throw new OSError($e->getMessage, $e->getCode());
} }
} }
static function getctime($path) { public static function getctime($path)
{
try { try {
$rc = filectime($path); $rc = filectime($path);
return $rc; return $rc;
} } catch (Exception $e) {
catch( Exception $e ) {
throw new OSError($e->getMessage, $e->getCode()); throw new OSError($e->getMessage, $e->getCode());
} }
} }
static function getsize($path) { public static function getsize($path)
{
try { try {
$rc = filesize($path); $rc = filesize($path);
return $rc; return $rc;
} } catch (Exception $e) {
catch( Exception $e ) {
throw new OSError($e->getMessage, $e->getCode()); throw new OSError($e->getMessage, $e->getCode());
} }
} }
static function isabs($path) { public static function isabs($path)
{
// fixme: implement check for windows. // fixme: implement check for windows.
return $path[0] == '/'; return $path[0] == '/';
} }
static function isfile($path) { public static function isfile($path)
{
return is_file($path); return is_file($path);
} }
static function isdir($path) { public static function isdir($path)
{
return is_dir($path); return is_dir($path);
} }
static function islink($path) { public static function islink($path)
{
return is_link($path); return is_link($path);
} }
static function ismount($path) { public static function ismount($path)
{
self::_unimplemented(); self::_unimplemented();
} }
static function split($path) { public static function split($path)
{
$parts = explode(DIRECTORY_SEPARATOR, $path); $parts = explode(DIRECTORY_SEPARATOR, $path);
$first = implode(DIRECTORY_SEPARATOR, array_slice($parts, 0, count($parts) - 1)); $first = implode(DIRECTORY_SEPARATOR, array_slice($parts, 0, count($parts) - 1));
$last = $parts[count($parts) - 1]; $last = $parts[count($parts) - 1];
return array($first, $last);
return [$first, $last];
} }
static function join($path, ...$paths) { public static function join($path, ...$paths)
{
$buf = rtrim($path, '/'); $buf = rtrim($path, '/');
foreach ($paths as $p) { foreach ($paths as $p) {
$i = 0; $i = 0;
$p = trim($p, '/'); $p = trim($p, '/');
$buf .= DIRECTORY_SEPARATOR.$p; $buf .= DIRECTORY_SEPARATOR.$p;
} }
return $buf; return $buf;
} }
static function normcase($path) { public static function normcase($path)
{
// fixme: different behavior on windows. // fixme: different behavior on windows.
return $path; return $path;
} }
static function normpath($path) { public static function normpath($path)
{
return realpath($path); return realpath($path);
} }
static function realpath($path) { public static function realpath($path)
{
return realpath($path); return realpath($path);
} }
static function relpath($path, $start) { public static function relpath($path, $start)
{
self::_unimplemented(); self::_unimplemented();
} }
static function samefile($path1, $path2) { public static function samefile($path1, $path2)
{
return fileinode($path1) == fileinode($path2); return fileinode($path1) == fileinode($path2);
} }
static function sameopenfile($fd1, $fd2) { public static function sameopenfile($fd1, $fd2)
{
$s1 = fstat($fd1); $s1 = fstat($fd1);
$s2 = fstat($fd2); $s2 = fstat($fd2);
return $s1['ino'] == $s2['ino']; return $s1['ino'] == $s2['ino'];
} }
static function samestat($stat1, $stat2) { public static function samestat($stat1, $stat2)
{
return $stat1 == $stat2; return $stat1 == $stat2;
} }
static function splitdrive($path) { public static function splitdrive($path)
{
//fixme: implement windows case. //fixme: implement windows case.
return array('', $path); return ['', $path];
} }
static function splitext($path) { public static function splitext($path)
{
$first = $path; $first = $path;
$second = ''; $second = '';
@ -195,20 +230,22 @@ class os_path {
$second = substr($path, $pos); $second = substr($path, $pos);
} }
return array($first, $second); return [$first, $second];
} }
static function splitunc($path) { public static function splitunc($path)
{
self::_unimplemented(); self::_unimplemented();
} }
static function walk($path, $visit, $arg) { public static function walk($path, $visit, $arg)
{
// Note: deprecated in python 3 in favor of os.walk() // Note: deprecated in python 3 in favor of os.walk()
self::_unimplemented(); self::_unimplemented();
} }
private static function _unimplemented() { private static function _unimplemented()
throw new Exception( "Unimplemented. Please consider submitting a patch to py2php project on github."); {
throw new Exception('Unimplemented. Please consider submitting a patch to py2php project on github.');
} }
} }

View File

@ -7,7 +7,8 @@
* It is called in this file; the parent php file(s) should use require_once and do * It is called in this file; the parent php file(s) should use require_once and do
* not need to make any call. * not need to make any call.
*/ */
function init_strict_mode() { function init_strict_mode()
{
// these are safe to call multiple times per process without dups. // these are safe to call multiple times per process without dups.
error_reporting(E_ALL | E_STRICT); error_reporting(E_ALL | E_STRICT);
@ -17,8 +18,7 @@ function init_strict_mode() {
// register_shutdown_function should only be called once per process to avoid dups. // register_shutdown_function should only be called once per process to avoid dups.
static $called = false; static $called = false;
if (!$called) { if (!$called) {
register_shutdown_function('shutdown_handler');
register_shutdown_function( "shutdown_handler" );
$called = true; $called = true;
} }
} }
@ -28,15 +28,16 @@ function init_strict_mode() {
* eg by a 3rd party lib. Any error handlers that were registered after * eg by a 3rd party lib. Any error handlers that were registered after
* ours are removed. * ours are removed.
*/ */
function restore_strict_error_handler() { function restore_strict_error_handler()
{
$e_handler_name = function () { $e_handler_name = function () {
$name = set_error_handler('restore_strict_error_handler'); // will never be used. $name = set_error_handler('restore_strict_error_handler'); // will never be used.
restore_error_handler(); restore_error_handler();
return $name; return $name;
}; };
while( !in_array( $e_handler_name(), array( '_global_error_handler', null ) ) ) { while (!in_array($e_handler_name(), ['_global_error_handler', null])) {
restore_error_handler(); restore_error_handler();
} }
if (!$e_handler_name()) { if (!$e_handler_name()) {
@ -49,15 +50,16 @@ function restore_strict_error_handler() {
* eg by a 3rd party lib. Any error handlers that were registered after * eg by a 3rd party lib. Any error handlers that were registered after
* ours are removed. * ours are removed.
*/ */
function restore_strict_exception_handler() { function restore_strict_exception_handler()
{
$exc_handler_name = function () { $exc_handler_name = function () {
$name = set_exception_handler('restore_strict_exception_handler'); // will never be used. $name = set_exception_handler('restore_strict_exception_handler'); // will never be used.
restore_exception_handler(); restore_exception_handler();
return $name; return $name;
}; };
while( !in_array( $exc_handler_name(), array( '_global_exception_handler', null ) ) ) { while (!in_array($exc_handler_name(), ['_global_exception_handler', null])) {
restore_exception_handler(); restore_exception_handler();
} }
if (!$exc_handler_name()) { if (!$exc_handler_name()) {
@ -72,7 +74,8 @@ function restore_strict_exception_handler() {
* *
* However, we allow the @operator in the code to override. * However, we allow the @operator in the code to override.
*/ */
function _global_error_handler($errno, $errstr, $errfile, $errline ) { function _global_error_handler($errno, $errstr, $errfile, $errline)
{
/* from php.net /* from php.net
* error_reporting() settings will have no effect and your error handler will * error_reporting() settings will have no effect and your error handler will
@ -91,7 +94,8 @@ function _global_error_handler($errno, $errstr, $errfile, $errline ) {
/*** /***
* This exception handler callback will be called for any exceptions that the application code does not catch. * This exception handler callback will be called for any exceptions that the application code does not catch.
*/ */
function _global_exception_handler( $e ) { function _global_exception_handler($e)
{
$msg = sprintf("\nUncaught Exception. code: %s, message: %s\n%s : %s\n\nStack Trace:\n%s\n", $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString()); $msg = sprintf("\nUncaught Exception. code: %s, message: %s\n%s : %s\n\nStack Trace:\n%s\n", $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString());
while (($e = $e->getPrevious())) { while (($e = $e->getPrevious())) {
$msg .= sprintf("\nPrevious Exception. code: %s, message: %s\n%s : %s\n\nStack Trace:\n%s\n", $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString()); $msg .= sprintf("\nPrevious Exception. code: %s, message: %s\n%s : %s\n\nStack Trace:\n%s\n", $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString());
@ -104,10 +108,10 @@ function _global_exception_handler( $e ) {
} }
/** /**
* This shutdown handler callback prints a message and sends email on any PHP fatal error * This shutdown handler callback prints a message and sends email on any PHP fatal error.
*/ */
function shutdown_handler() { function shutdown_handler()
{
$error = error_get_last(); $error = error_get_last();
$ignore = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_DEPRECATED | E_USER_DEPRECATED; $ignore = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_DEPRECATED | E_USER_DEPRECATED;
@ -121,14 +125,14 @@ function shutdown_handler() {
} }
/** /**
* email admin if defined * email admin if defined.
*/ */
function strict_mode_mail_admin( $subject, $msg ) { function strict_mode_mail_admin($subject, $msg)
{
$subject = sprintf('[%s] [%s] %s [pid: %s]', gethostname(), basename($_SERVER['PHP_SELF']), $subject, getmypid()); $subject = sprintf('[%s] [%s] %s [pid: %s]', gethostname(), basename($_SERVER['PHP_SELF']), $subject, getmypid());
if (defined('ALERTS_MAIL_TO')) { if (defined('ALERTS_MAIL_TO')) {
mail(ALERTS_MAIL_TO, $subject, $msg); mail(ALERTS_MAIL_TO, $subject, $msg);
} } else {
else {
echo "\nWARNING: ALERTS_MAIL_TO not defined in environment. alert not sent with subject: $subject\n"; echo "\nWARNING: ALERTS_MAIL_TO not defined in environment. alert not sent with subject: $subject\n";
} }
} }

View File

@ -1,25 +1,30 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
require_once ('os_path.php'); require_once 'os_path.php';
require_once ('crypt.php'); require_once 'crypt.php';
require_once ('prime.php'); require_once 'prime.php';
require_once ('TL.php'); require_once 'TL.php';
require_once ('Struct.php'); require_once 'Struct.php';
/** /**
* Function to get hex crc32 * Function to get hex crc32
* :param data: Data to encode * :param data: Data to encode.
*/ */
function newcrc32($data) { function newcrc32($data)
return hexdec(hash("crc32b", $data)); {
return hexdec(hash('crc32b', $data));
} }
/** /**
* Function to dump the hex version of a string. * Function to dump the hex version of a string.
* :param what: What to dump * :param what: What to dump.
*/ */
function hex_dump($what) { var_dump(bin2hex($what)); }; function hex_dump($what)
{
var_dump(bin2hex($what));
}
/** /**
* len. * len.
* *
@ -40,21 +45,26 @@ function hex_dump($what) { var_dump(bin2hex($what)); };
/** /**
* Function to visualize byte streams. Split into bytes, print to console. * Function to visualize byte streams. Split into bytes, print to console.
* :param bs: BYTE STRING * :param bs: BYTE STRING.
*/ */
function vis($bs) { function vis($bs)
{
$bs = str_split($bs); $bs = str_split($bs);
$symbols_in_one_line = 8; $symbols_in_one_line = 8;
$n = floor(len($bs) / $symbols_in_one_line); $n = floor(len($bs) / $symbols_in_one_line);
$i = 0; $i = 0;
foreach (pyjslib_range($n) as $i) { foreach (pyjslib_range($n) as $i) {
echo $i * $symbols_in_one_line . ' | ' . join(' ', echo $i * $symbols_in_one_line.' | '.implode(' ',
array_map(function($el) { return bin2hex($el); }, array_slice($bs,$i*$symbols_in_one_line, ($i+1)*$symbols_in_one_line)) array_map(function ($el) {
return bin2hex($el);
}, array_slice($bs, $i * $symbols_in_one_line, ($i + 1) * $symbols_in_one_line))
).PHP_EOL; ).PHP_EOL;
} }
if (!(len($bs) % $symbols_in_one_line == 0)) { if (!(len($bs) % $symbols_in_one_line == 0)) {
echo ($i + 1) * $symbols_in_one_line . ' | ' . join(' ', echo($i + 1) * $symbols_in_one_line.' | '.implode(' ',
array_map(function($el) { return bin2hex($el); }, array_slice($bs, ($i+1)*$symbols_in_one_line)) array_map(function ($el) {
return bin2hex($el);
}, array_slice($bs, ($i + 1) * $symbols_in_one_line))
).PHP_EOL; ).PHP_EOL;
} }
} }
@ -63,7 +73,8 @@ function vis($bs) {
* Convert a byte string to a long integer. * Convert a byte string to a long integer.
* This is (essentially) the inverse of long_to_bytes(). * This is (essentially) the inverse of long_to_bytes().
*/ */
function bytes_to_long($s) { function bytes_to_long($s)
{
$acc = 0; $acc = 0;
$length = strlen($s); $length = strlen($s);
if (($length % 4)) { if (($length % 4)) {
@ -74,20 +85,25 @@ function bytes_to_long($s) {
foreach (pyjslib_range(0, $length, 4) as $i) { foreach (pyjslib_range(0, $length, 4) as $i) {
$acc = ($acc << 32 + $this->struct->unpack('I', array_slice($s, $i, ($i + 4) - $i))[0]); $acc = ($acc << 32 + $this->struct->unpack('I', array_slice($s, $i, ($i + 4) - $i))[0]);
} }
return $acc; return $acc;
} }
function fread_all($handle) { function fread_all($handle)
{
$pos = ftell($handle); $pos = ftell($handle);
fseek($handle, 0); fseek($handle, 0);
$content = fread($handle, fstat($handle)["size"]); $content = fread($handle, fstat($handle)['size']);
fseek($handle, $pos); fseek($handle, $pos);
return $content; return $content;
} }
function fopen_and_write($filename, $mode, $data) { function fopen_and_write($filename, $mode, $data)
{
$handle = fopen($filename, $mode); $handle = fopen($filename, $mode);
fwrite($handle, $data); fwrite($handle, $data);
rewind($handle); rewind($handle);
return $handle; return $handle;
} }
/** /**
@ -97,7 +113,8 @@ function fopen_and_write($filename, $mode, $data) {
* byte string with binary zeros so that the length is a multiple of * byte string with binary zeros so that the length is a multiple of
* blocksize. * blocksize.
*/ */
function long_to_bytes($n,$blocksize=0) { function long_to_bytes($n, $blocksize = 0)
{
$s = $b(''); $s = $b('');
$n = long($n); $n = long($n);
while (($n > 0)) { while (($n > 0)) {
@ -113,24 +130,31 @@ function long_to_bytes($n,$blocksize=0) {
if (($blocksize > 0) && (strlen($s) % $blocksize)) { if (($blocksize > 0) && (strlen($s) % $blocksize)) {
$s = ((($blocksize - (strlen($s) % $blocksize)) * $b('')) + $s); $s = ((($blocksize - (strlen($s) % $blocksize)) * $b('')) + $s);
} }
return $s; return $s;
} }
function string2bin($string) { function string2bin($string)
{
$res = null; $res = null;
foreach (explode('\\', $string) as $s) { foreach (explode('\\', $string) as $s) {
if($s != null && $s[0] == "x") { if ($s != null && $s[0] == 'x') {
$res .= hex2bin(substr($s, 1)); $res .= hex2bin(substr($s, 1));
} }
} }
return $res; return $res;
} }
/** /**
* Manages TCP Transport. encryption and message frames * Manages TCP Transport. encryption and message frames.
*/ */
class Session { class Session
function __construct($ip, $port, $auth_key = null, $server_salt = null) { {
$this->sock = fsockopen("tcp://".$ip.":".$port); public function __construct($ip, $port, $auth_key = null, $server_salt = null)
if(!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) throw new Exception("Couldn't connect to socket."); {
$this->sock = fsockopen('tcp://'.$ip.':'.$port);
if (!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) {
throw new Exception("Couldn't connect to socket.");
}
$this->number = 0; $this->number = 0;
$this->timedelta = 0; $this->timedelta = 0;
$this->session_id = random_bytes(8); $this->session_id = random_bytes(8);
@ -141,19 +165,23 @@ class Session {
$this->AUTH_MAX_RETRY = 5; $this->AUTH_MAX_RETRY = 5;
$this->struct = new \danog\PHP\Struct(); $this->struct = new \danog\PHP\Struct();
try { try {
$this->tl = new TL("https://core.telegram.org/schema/mtproto-json"); $this->tl = new TL('https://core.telegram.org/schema/mtproto-json');
} catch (Exception $e) { } catch (Exception $e) {
$this->tl = new TL(__DIR__.'/TL_schema.JSON'); $this->tl = new TL(__DIR__.'/TL_schema.JSON');
} }
} }
function __destruct() {
public function __destruct()
{
fclose($this->sock); fclose($this->sock);
} }
/** /**
* Forming the message frame and sending message to server * Forming the message frame and sending message to server
* :param message: byte string to send * :param message: byte string to send.
*/ */
function send_message($message_data) { public function send_message($message_data)
{
$message_id = $this->struct->pack('<Q', (int) ((time() + $this->timedelta) * pow(2, 30)) * 4); $message_id = $this->struct->pack('<Q', (int) ((time() + $this->timedelta) * pow(2, 30)) * 4);
if (($this->auth_key == null) || ($this->server_salt == null)) { if (($this->auth_key == null) || ($this->server_salt == null)) {
@ -172,10 +200,12 @@ class Session {
fwrite($this->sock, $step2); fwrite($this->sock, $step2);
$this->number += 1; $this->number += 1;
} }
/** /**
* Reading socket and receiving message from server. Check the CRC32. * Reading socket and receiving message from server. Check the CRC32.
*/ */
function recv_message() { public function recv_message()
{
$packet_length_data = fread($this->sock, 4); $packet_length_data = fread($this->sock, 4);
if (len($packet_length_data) < 4) { if (len($packet_length_data) < 4) {
throw new Exception('Nothing in the socket!'); throw new Exception('Nothing in the socket!');
@ -188,7 +218,7 @@ class Session {
$x = $this->struct->unpack('<I', substr($packet, null, 4)); $x = $this->struct->unpack('<I', substr($packet, null, 4));
$auth_key_id = substr($packet, 4, 12 - 4); $auth_key_id = substr($packet, 4, 12 - 4);
if ($auth_key_id == string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) { if ($auth_key_id == string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) {
list($message_id, $message_length) = struct.unpack("<8sI", substr($packet, 12, 24)); list($message_id, $message_length) = struct.unpack('<8sI', substr($packet, 12, 24));
$data = substr($packet, 24, (24 + $message_length) - 24); $data = substr($packet, 24, (24 + $message_length) - 24);
} elseif ($auth_key_id == $this->auth_key_id) { } elseif ($auth_key_id == $this->auth_key_id) {
$message_key = substr($packet, 12, 28 - 12); $message_key = substr($packet, 12, 28 - 12);
@ -204,27 +234,32 @@ class Session {
} else { } else {
throw new Exception('Got unknown auth_key id'); throw new Exception('Got unknown auth_key id');
} }
return $data; return $data;
} }
function method_call($method, $kwargs) {
public function method_call($method, $kwargs)
{
foreach (range(1, $this->MAX_RETRY) as $i) { foreach (range(1, $this->MAX_RETRY) as $i) {
try { try {
//var_dump(py2php_kwargs_function_call('serialize_method', [$method], $kwargs)); //var_dump(py2php_kwargs_function_call('serialize_method', [$method], $kwargs));
$this->send_message($this->tl->serialize_method($method, $kwargs)); $this->send_message($this->tl->serialize_method($method, $kwargs));
$server_answer = $this->recv_message(); $server_answer = $this->recv_message();
} } catch (Exception $e) {
catch(Exception $e) {
echo $e->getMessage().PHP_EOL; echo $e->getMessage().PHP_EOL;
pyjslib_printnl('Retry call method'); pyjslib_printnl('Retry call method');
continue; continue;
} }
return $this->tl->deserialize(fopen_and_write("php://memory", "rw+b", $server_answer));
return $this->tl->deserialize(fopen_and_write('php://memory', 'rw+b', $server_answer));
} }
} }
function create_auth_key() {
public function create_auth_key()
{
$nonce = random_bytes(16); $nonce = random_bytes(16);
pyjslib_printnl('Requesting pq'); pyjslib_printnl('Requesting pq');
$ResPQ = $this->method_call('req_pq', ["nonce" => $nonce]); $ResPQ = $this->method_call('req_pq', ['nonce' => $nonce]);
$server_nonce = $ResPQ['server_nonce']; $server_nonce = $ResPQ['server_nonce'];
$public_key_fingerprint = $ResPQ['server_public_key_fingerprints'][0]; $public_key_fingerprint = $ResPQ['server_public_key_fingerprints'][0];
$pq_bytes = $ResPQ['pq']; $pq_bytes = $ResPQ['pq'];
@ -240,13 +275,13 @@ class Session {
$f = pyjslib_open(__DIR__.'/rsa.pub'); $f = pyjslib_open(__DIR__.'/rsa.pub');
$key = RSA::importKey($f->read()); $key = RSA::importKey($f->read());
$new_nonce = random_bytes(32); $new_nonce = random_bytes(32);
$data = py2php_kwargs_function_call('serialize_obj', ['p_q_inner_data'], ["pq" => $pq_bytes, "p" => $p_bytes, "q" => $q_bytes, "nonce" => $nonce, "server_nonce" => $server_nonce, "new_nonce" => $new_nonce]); $data = py2php_kwargs_function_call('serialize_obj', ['p_q_inner_data'], ['pq' => $pq_bytes, 'p' => $p_bytes, 'q' => $q_bytes, 'nonce' => $nonce, 'server_nonce' => $server_nonce, 'new_nonce' => $new_nonce]);
$sha_digest = sha($data, true); $sha_digest = sha($data, true);
$random_bytes = random_bytes(((255 - strlen($data)) - strlen($sha_digest))); $random_bytes = random_bytes(((255 - strlen($data)) - strlen($sha_digest)));
$to_encrypt = (($sha_digest + $data) + $random_bytes); $to_encrypt = (($sha_digest + $data) + $random_bytes);
$encrypted_data = $key->encrypt($to_encrypt, 0) [0]; $encrypted_data = $key->encrypt($to_encrypt, 0) [0];
pyjslib_printnl('Starting Diffie Hellman key exchange'); pyjslib_printnl('Starting Diffie Hellman key exchange');
$server_dh_params = $this->method_call('req_DH_params', ["nonce" => $nonce, "server_nonce" => $server_nonce, "p" => $p_bytes, "q" => $q_bytes, "public_key_fingerprint" => $public_key_fingerprint, "encrypted_data" => $encrypted_data]); $server_dh_params = $this->method_call('req_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'p' => $p_bytes, 'q' => $q_bytes, 'public_key_fingerprint' => $public_key_fingerprint, 'encrypted_data' => $encrypted_data]);
assert(($nonce == $server_dh_params['nonce'])); assert(($nonce == $server_dh_params['nonce']));
assert(($server_nonce == $server_dh_params['server_nonce'])); assert(($server_nonce == $server_dh_params['server_nonce']));
$encrypted_answer = $server_dh_params['encrypted_answer']; $encrypted_answer = $server_dh_params['encrypted_answer'];
@ -272,12 +307,12 @@ class Session {
$b = new bytes_to_long($b_str); $b = new bytes_to_long($b_str);
$g_b = pow($g, $b, $dh_prime); $g_b = pow($g, $b, $dh_prime);
$g_b_str = new long_to_bytes($g_b); $g_b_str = new long_to_bytes($g_b);
$data = py2php_kwargs_function_call('serialize_obj', ['client_DH_inner_data'], ["nonce" => $nonce, "server_nonce" => $server_nonce, "retry_id" => $retry_id, "g_b" => $g_b_str]); $data = py2php_kwargs_function_call('serialize_obj', ['client_DH_inner_data'], ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'retry_id' => $retry_id, 'g_b' => $g_b_str]);
$data_with_sha = (sha1($data, true) + $data); $data_with_sha = (sha1($data, true) + $data);
$data_with_sha_padded = ($data_with_sha + random_bytes((-strlen($data_with_sha) % 16))); $data_with_sha_padded = ($data_with_sha + random_bytes((-strlen($data_with_sha) % 16)));
$encrypted_data = crypt::ige_encrypt($data_with_sha_padded, $tmp_aes_key, $tmp_aes_iv); $encrypted_data = crypt::ige_encrypt($data_with_sha_padded, $tmp_aes_key, $tmp_aes_iv);
foreach (pyjslib_range(1, $this->AUTH_MAX_RETRY) as $i) { foreach (pyjslib_range(1, $this->AUTH_MAX_RETRY) as $i) {
$Set_client_DH_params_answer = $this->method_call('set_client_DH_params', ["nonce" => $nonce, "server_nonce" => $server_nonce, "encrypted_data" => $encrypted_data]); $Set_client_DH_params_answer = $this->method_call('set_client_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'encrypted_data' => $encrypted_data]);
$auth_key = pow($g_a, $b, $dh_prime); $auth_key = pow($g_a, $b, $dh_prime);
$auth_key_str = new long_to_bytes($auth_key); $auth_key_str = new long_to_bytes($auth_key);
$auth_key_sha = sha1($auth_key_str, true); $auth_key_sha = sha1($auth_key_str, true);
@ -294,6 +329,7 @@ class Session {
$this->auth_key = $auth_key_str; $this->auth_key = $auth_key_str;
$this->auth_key_id = array_slice($auth_key_sha, -8, null); $this->auth_key_id = array_slice($auth_key_sha, -8, null);
pyjslib_printnl('Auth key generated'); pyjslib_printnl('Auth key generated');
return 'Auth Ok'; return 'Auth Ok';
} elseif (($Set_client_DH_params_answer->name == 'dh_gen_retry')) { } elseif (($Set_client_DH_params_answer->name == 'dh_gen_retry')) {
assert(($Set_client_DH_params_answer['new_nonce_hash2'] == $new_nonce_hash2)); assert(($Set_client_DH_params_answer['new_nonce_hash2'] == $new_nonce_hash2));
@ -307,7 +343,9 @@ class Session {
} }
} }
} }
function aes_calculate($msg_key, $direction = 'to server') {
public function aes_calculate($msg_key, $direction = 'to server')
{
$x = ($direction == 'to server') ? 0 : 8; $x = ($direction == 'to server') ? 0 : 8;
$sha1_a = sha1(($msg_key + array_slice($this->auth_key, $x, ($x + 32) - $x)), true); $sha1_a = sha1(($msg_key + array_slice($this->auth_key, $x, ($x + 32) - $x)), true);
$sha1_b = sha1(((array_slice($this->auth_key, ($x + 32), ($x + 48) - ($x + 32)) + $msg_key) + array_slice($this->auth_key, (48 + $x), (64 + $x) - (48 + $x))), true); $sha1_b = sha1(((array_slice($this->auth_key, ($x + 32), ($x + 48) - ($x + 32)) + $msg_key) + array_slice($this->auth_key, (48 + $x), (64 + $x) - (48 + $x))), true);
@ -315,6 +353,7 @@ class Session {
$sha1_d = sha1(($msg_key + array_slice($this->auth_key, ($x + 96), ($x + 128) - ($x + 96))))->digest(); $sha1_d = sha1(($msg_key + array_slice($this->auth_key, ($x + 96), ($x + 128) - ($x + 96))))->digest();
$aes_key = ((array_slice($sha1_a, 0, 8 - 0) + array_slice($sha1_b, 8, 20 - 8)) + array_slice($sha1_c, 4, 16 - 4)); $aes_key = ((array_slice($sha1_a, 0, 8 - 0) + array_slice($sha1_b, 8, 20 - 8)) + array_slice($sha1_c, 4, 16 - 4));
$aes_iv = (((array_slice($sha1_a, 8, 20 - 8) + array_slice($sha1_b, 0, 8 - 0)) + array_slice($sha1_c, 16, 20 - 16)) + array_slice($sha1_d, 0, 8 - 0)); $aes_iv = (((array_slice($sha1_a, 8, 20 - 8) + array_slice($sha1_b, 0, 8 - 0)) + array_slice($sha1_c, 16, 20 - 16)) + array_slice($sha1_d, 0, 8 - 0));
return [$aes_key, $aes_iv]; return [$aes_key, $aes_iv];
} }
} }

View File

@ -1,8 +1,10 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
function everynth($array, $n) { function everynth($array, $n)
$result = array(); {
$result = [];
$i = -1; $i = -1;
foreach ($array as $key => $value) { foreach ($array as $key => $value) {
if ($i++ == $n) { if ($i++ == $n) {
@ -12,18 +14,24 @@ function everynth($array, $n) {
$result[$key] = $value; $result[$key] = $value;
} }
} }
return $result; return $result;
} }
function array_merge_ignore_keys($array1, $array2) { function array_merge_ignore_keys($array1, $array2)
{
if (count($array1) == count($array2)) { if (count($array1) == count($array2)) {
$i = -1; $i = -1;
foreach ($array1 as $key => $val) { foreach ($array1 as $key => $val) {
$array1[$key] = $array2[$i++]; $array1[$key] = $array2[$i++];
} }
} else return null; } else {
return;
}
return $array1; return $array1;
} }
function primesbelow($N) { function primesbelow($N)
{
$correction = (($N % 6) > 1); $correction = (($N % 6) > 1);
$N = [0 => $N, 1 => ($N - 1), 2 => ($N + 4), 3 => ($N + 3), 4 => ($N + 2), 5 => ($N + 1)][($N % 6)]; $N = [0 => $N, 1 => ($N - 1), 2 => ($N + 4), 3 => ($N + 3), 4 => ($N + 2), 5 => ($N + 1)][($N % 6)];
$sieve = array_fill(0, floor($N / 3), true); $sieve = array_fill(0, floor($N / 3), true);
@ -71,11 +79,17 @@ function primesbelow($N) {
); );
} }
} }
return ([2, 3] + array_map(function ($i, $sieve) { if($sieve[$i]) return (3 * $i + 1) | 1; }, pyjslib_range(1, (($N / 3) - $correction)), $sieve));
return [2, 3] + array_map(function ($i, $sieve) {
if ($sieve[$i]) {
return (3 * $i + 1) | 1;
}
}, pyjslib_range(1, (($N / 3) - $correction)), $sieve);
} }
$smallprimeset = array_unique(primesbelow(100000)); $smallprimeset = array_unique(primesbelow(100000));
$_smallprimeset = 100000; $_smallprimeset = 100000;
function isprime($n, $precision = 7) { function isprime($n, $precision = 7)
{
if (($n == 1) || (($n % 2) == 0)) { if (($n == 1) || (($n % 2) == 0)) {
return false; return false;
} elseif (($n < 1)) { } elseif (($n < 1)) {
@ -105,9 +119,11 @@ function isprime($n, $precision = 7) {
} }
} }
} }
return true; return true;
} }
function pollard_brent($n) { function pollard_brent($n)
{
if ((($n % 2) == 0)) { if ((($n % 2) == 0)) {
return 2; return 2;
} }
@ -142,10 +158,12 @@ function pollard_brent($n) {
} }
} }
} }
return $g; return $g;
} }
$smallprimes = primesbelow(10000); $smallprimes = primesbelow(10000);
function primefactors($n, $sort = false) { function primefactors($n, $sort = false)
{
global $smallprimes; global $smallprimes;
$factors = []; $factors = [];
$limit = (pyjslib_int(pow($n, 0.5)) + 1); $limit = (pyjslib_int(pow($n, 0.5)) + 1);
@ -173,51 +191,56 @@ function primefactors($n, $sort = false) {
$factor = pollard_brent($n); $factor = pollard_brent($n);
$factors->extend(primefactors($factor)); $factors->extend(primefactors($factor));
$n = floor($n / $factor); $n = floor($n / $factor);
} }
if ($sort) { if ($sort) {
$factors->sort(); $factors->sort();
} }
return $factors; return $factors;
} }
function factorization($n) { function factorization($n)
{
$factors = []; $factors = [];
foreach (primefactors($n) as $p1) { foreach (primefactors($n) as $p1) {
try { try {
$factors[$p1] += 1; $factors[$p1] += 1;
} } catch (KeyError $e) {
catch(KeyError $e) {
$factors[$p1] = 1; $factors[$p1] = 1;
} }
} }
return $factors; return $factors;
} }
$totients = []; $totients = [];
function totient($n) { function totient($n)
{
if (($n == 0)) { if (($n == 0)) {
return 1; return 1;
} }
try { try {
return $totients[$n]; return $totients[$n];
} } catch (KeyError $e) {
catch(KeyError $e) {
} }
$tot = 1; $tot = 1;
foreach (factorization($n)->items() as list($p, $exp)) { foreach (factorization($n)->items() as list($p, $exp)) {
$tot *= (($p - 1) * pow($p, ($exp - 1))); $tot *= (($p - 1) * pow($p, ($exp - 1)));
} }
$totients[$n] = $tot; $totients[$n] = $tot;
return $tot; return $tot;
} }
function gcd($a, $b) { function gcd($a, $b)
{
if (($a == $b)) { if (($a == $b)) {
return $a; return $a;
} }
while (($b > 0)) { while (($b > 0)) {
list($a, $b) = [$b, ($a % $b)]; list($a, $b) = [$b, ($a % $b)];
} }
return $a; return $a;
} }
function lcm($a, $b) { function lcm($a, $b)
{
return floor(abs(($a * $b)) / gcd($a, $b)); return floor(abs(($a * $b)) / gcd($a, $b));
} }

View File

@ -1,27 +1,30 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
require_once ('mtproto.php'); require_once 'mtproto.php';
require_once ('classes/shell.php'); require_once 'classes/shell.php';
if (!debug_backtrace()) { if (!debug_backtrace()) {
$clidata = []; $clidata = [];
$clidata["description"] = 'MadelineProto: PHP implementation of telegram API. Translated from telepy by Daniil Gentili.'; $clidata['description'] = 'MadelineProto: PHP implementation of telegram API. Translated from telepy by Daniil Gentili.';
$clidata['args']['commands'] = array_merge(['cmd', 'dialog_list', 'contact_list'], array_map(function($sub) { return "chat_" . $sub; }, ['info', 'add_user', 'add_user_to_chat', 'del_user', 'set_photo', 'rename'])); $clidata['args']['commands'] = array_merge(['cmd', 'dialog_list', 'contact_list'], array_map(function ($sub) {
$clidata['args']['flags'] = "h"; return 'chat_'.$sub;
$clidata["help"] = $clidata["description"] . PHP_EOL . PHP_EOL . "Flags: "; }, ['info', 'add_user', 'add_user_to_chat', 'del_user', 'set_photo', 'rename']));
$clidata['args']['flags'] = 'h';
$clidata['help'] = $clidata['description'].PHP_EOL.PHP_EOL.'Flags: ';
foreach (str_split($clidata['args']['flags']) as $flag) { foreach (str_split($clidata['args']['flags']) as $flag) {
$clidata["help"] .= "-" . $flag . ", "; $clidata['help'] .= '-'.$flag.', ';
} }
$clidata["help"] .= PHP_EOL . "Commands: "; $clidata['help'] .= PHP_EOL.'Commands: ';
foreach ($clidata['args']['commands'] as $command) { foreach ($clidata['args']['commands'] as $command) {
$clidata["help"] .= $command . ", "; $clidata['help'] .= $command.', ';
} }
$clidata["help"] .= PHP_EOL; $clidata['help'] .= PHP_EOL;
if(isset(getopt($clidata['args']['flags'])["h"])) { if (isset(getopt($clidata['args']['flags'])['h'])) {
die($clidata["help"]); die($clidata['help']);
} }
if ($argc == 1) { if ($argc == 1) {
$newTelePyShell = new TelepyShell(); $newTelePyShell = new TelepyShell();

View File

@ -1,8 +1,9 @@
<?php <?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once ('libpy2php.php'); require_once 'libpy2php.php';
require_once ('os.php'); require_once 'os.php';
require_once ('mtproto.php'); require_once 'mtproto.php';
$config = parse_ini_file('credentials', true); $config = parse_ini_file('credentials', true);
if (!($config)) { if (!($config)) {
pyjslib_printnl('File \'credentials\' seems to not exist.'); pyjslib_printnl('File \'credentials\' seems to not exist.');