Applied fixes from StyleCI

This commit is contained in:
Daniil Gentili 2016-07-14 09:15:50 -04:00 committed by StyleCI Bot
parent e14d08750a
commit 2187acbf09
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
*/
class AES {
class AES
{
// The number of 32-bit words comprising the plaintext and columns comrising the state matrix of an AES cipher.
private static $Nb = 4;
// The number of 32-bit words comprising the cipher key in this AES cipher.
@ -27,7 +28,7 @@ class AES {
private $Nr;
// The S-Box substitution table.
private static $sBox = array(
private static $sBox = [
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
@ -59,11 +60,11 @@ class AES {
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
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.
private static $invSBox = array(
private static $invSBox = [
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
@ -95,11 +96,11 @@ class AES {
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
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
private static $ltable = array(
private static $ltable = [
0x00, 0xff, 0xc8, 0x08, 0x91, 0x10, 0xd0, 0x36,
0x5a, 0x3e, 0xd8, 0x43, 0x99, 0x77, 0xfe, 0x18,
0x23, 0x20, 0x07, 0x70, 0xa1, 0x6c, 0x0c, 0x7f,
@ -131,11 +132,11 @@ class AES {
0x22, 0x88, 0x94, 0xce, 0x19, 0x01, 0x71, 0x4c,
0xa5, 0xe3, 0xc5, 0x31, 0xbb, 0xcc, 0x1f, 0x2d,
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
private static $atable = array(
private static $atable = [
0x01, 0xe5, 0x4c, 0xb5, 0xfb, 0x9f, 0xfc, 0x12,
0x03, 0x34, 0xd4, 0xc4, 0x16, 0xba, 0x1f, 0x36,
0x05, 0x5c, 0x67, 0x57, 0x3a, 0xd5, 0x21, 0x5a,
@ -167,8 +168,8 @@ class AES {
0x1e, 0xd3, 0x49, 0xe9, 0x9c, 0xc8, 0xc6, 0xc7,
0x22, 0x6e, 0xdb, 0x20, 0xbf, 0x43, 0x51, 0x52,
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.
private $w;
@ -180,16 +181,18 @@ class AES {
/** constructs an AES cipher using a specific key.
*/
public function __construct($z) {
$this->Nk = strlen($z)/4;
public function __construct($z)
{
$this->Nk = strlen($z) / 4;
$this->Nr = $this->Nk + self::$Nb + 2;
if ($this->Nk != 4 && $this->Nk != 6 && $this->Nk != 8)
die("Key is " . ($this->Nk*32) . " bits long. *not* 128, 192, or 256.");
if ($this->Nk != 4 && $this->Nk != 6 && $this->Nk != 8) {
die('Key is '.($this->Nk * 32).' bits long. *not* 128, 192, or 256.');
}
$this->Nr = $this->Nk+self::$Nb+2;
$this->w = array(); // Nb*(Nr+1) 32-bit words
$this->s = array(array()); // 2-D array of Nb colums and 4 rows
$this->Nr = $this->Nk + self::$Nb + 2;
$this->w = []; // Nb*(Nr+1) 32-bit words
$this->s = [[]]; // 2-D array of Nb colums and 4 rows
$this->KeyExpansion($z); // places expanded key in w
}
@ -201,23 +204,25 @@ class AES {
* encryptBlock() function directly, as the amount of time required
* to encrypt is linear to the size of the ciphertext.
**/
public function encrypt($x) {
$t = ""; // 16-byte block
$y = ""; // returned cipher text;
public function encrypt($x)
{
$t = ''; // 16-byte block
$y = ''; // returned cipher text;
// put a 16-byte block into t
$xsize = strlen($x);
for ($i=0; $i<$xsize; $i+=16) {
for ($j=0; $j<16; $j++) {
if (($i+$j)<$xsize) {
$t[$j] = $x[$i+$j];
}
else
for ($i = 0; $i < $xsize; $i += 16) {
for ($j = 0; $j < 16; $j++) {
if (($i + $j) < $xsize) {
$t[$j] = $x[$i + $j];
} else {
$t[$j] = chr(0);
}
}
$y .= $this->encryptBlock($t);
}
return $y;
}
@ -228,21 +233,24 @@ class AES {
* decryptBlock() function directly, as the amount of time required
* to decrypt is linear to the size of the ciphertext.
**/
public function decrypt($y) {
$t = ""; // 16-byte block
$x = ""; // returned plain text;
public function decrypt($y)
{
$t = ''; // 16-byte block
$x = ''; // returned plain text;
// put a 16-byte block into t
$ysize = strlen($y);
for ($i=0; $i<$ysize; $i+=16) {
for ($j=0; $j<16; $j++) {
if (($i+$j)<$ysize)
$t[$j] = $y[$i+$j];
else
for ($i = 0; $i < $ysize; $i += 16) {
for ($j = 0; $j < 16; $j++) {
if (($i + $j) < $ysize) {
$t[$j] = $y[$i + $j];
} else {
$t[$j] = chr(0);
}
}
$x .= $this->decryptBlock($t);
}
return $x;
}
@ -250,19 +258,20 @@ class AES {
* @params 16-byte plaintext string
* @returns 16-byte ciphertext string
**/
public function encryptBlock($x) {
$y = ""; // 16-byte string
public function encryptBlock($x)
{
$y = ''; // 16-byte string
// 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++) {
// we want integerger division for the second index
$this->s[$i%4][($i-$i%self::$Nb)/self::$Nb] = ord($x[$i]);
$this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb] = ord($x[$i]);
}
// add round key
$this->addRoundKey(0);
for ($i=1; $i<$this->Nr; $i++) {
for ($i = 1; $i < $this->Nr; $i++) {
// substitute bytes
$this->subBytes();
@ -286,8 +295,10 @@ class AES {
$this->addRoundKey($i);
// place state matrix s into y in column order
for ($i=0; $i<4*self::$Nb; $i++)
$y .= chr($this->s[$i%4][($i-$i%self::$Nb)/self::$Nb]);
for ($i = 0; $i < 4 * self::$Nb; $i++) {
$y .= chr($this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb]);
}
return $y;
}
@ -295,17 +306,19 @@ class AES {
* @params 16-byte ciphertext string
* @returns 16-byte plaintext string
**/
public function decryptBlock($y) {
$x = ""; // 16-byte string
public function decryptBlock($y)
{
$x = ''; // 16-byte string
// place input y into the initial state matrix in column order
for ($i=0; $i<4*self::$Nb; $i++)
$this->s[$i%4][($i-$i%self::$Nb)/self::$Nb] = ord($y[$i]);
for ($i = 0; $i < 4 * self::$Nb; $i++) {
$this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb] = ord($y[$i]);
}
// add round key
$this->addRoundKey($this->Nr);
for ($i=$this->Nr-1; $i>0; $i--) {
for ($i = $this->Nr - 1; $i > 0; $i--) {
// inverse shift rows
$this->invShiftRows();
@ -329,15 +342,16 @@ class AES {
$this->addRoundKey($i);
// 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.
$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;
}
public function __destruct() {
public function __destruct()
{
unset($this->w);
unset($this->s);
}
@ -345,9 +359,10 @@ class AES {
/** makes a big key out of a small one
* @returns void
**/
private function KeyExpansion($z) {
private function KeyExpansion($z)
{
// Rcon is the round constant
static $Rcon = array(
static $Rcon = [
0x00000000,
0x01000000,
0x02000000,
@ -364,35 +379,36 @@ class AES {
0xab000000,
0x4d000000,
0x9a000000,
0x2f000000
);
0x2f000000,
];
$temp = 0; // temporary 32-bit word
// the first Nk words of w are the cipher key z
for ($i=0; $i<$this->Nk; $i++) {
for ($i = 0; $i < $this->Nk; $i++) {
$this->w[$i] = 0;
// fill an entire word of expanded key w
// by pushing 4 bytes into the w[i] word
$this->w[$i] = ord($z[4*$i]); // add a byte in
$this->w[$i] = ord($z[4 * $i]); // add a byte in
$this->w[$i] <<= 8; // make room for the next byte
$this->w[$i] += ord($z[4*$i+1]);
$this->w[$i] += ord($z[4 * $i + 1]);
$this->w[$i] <<= 8;
$this->w[$i] += ord($z[4*$i+2]);
$this->w[$i] += ord($z[4 * $i + 2]);
$this->w[$i] <<= 8;
$this->w[$i] += ord($z[4*$i+3]);
$this->w[$i] += ord($z[4 * $i + 3]);
}
for (; $i<self::$Nb*($this->Nr+1); $i++) {
$temp = $this->w[$i-1];
for (; $i < self::$Nb * ($this->Nr + 1); $i++) {
$temp = $this->w[$i - 1];
if ($i%$this->Nk == 0)
$temp = $this->subWord($this->rotWord($temp)) ^ $Rcon[$i/$this->Nk];
else if ($this->Nk > 6 && $i%$this->Nk == 4)
if ($i % $this->Nk == 0) {
$temp = $this->subWord($this->rotWord($temp)) ^ $Rcon[$i / $this->Nk];
} elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
$temp = $this->subWord($temp);
}
$this->w[$i] = $this->w[$i-$this->Nk] ^ $temp;
$this->w[$i] = $this->w[$i - $this->Nk] ^ $temp;
self::make32BitWord($this->w[$i]);
}
@ -401,13 +417,14 @@ class AES {
/** adds the key schedule for a round to a state matrix.
* @returns void
**/
private function addRoundKey($round) {
$temp = "";
private function addRoundKey($round)
{
$temp = '';
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++) {
// place the i-th byte of the j-th word from expanded key w into temp
$temp = $this->w[$round*self::$Nb+$j] >> (3-$i)*8;
$temp = $this->w[$round * self::$Nb + $j] >> (3 - $i) * 8;
// Cast temp from a 32-bit word into an 8-bit byte.
$temp %= 256;
// Can't do unsigned shifts, so we need to make this temp positive
@ -421,52 +438,65 @@ class AES {
/** unmixes each column of a state matrix.
* @returns void
**/
private function invMixColumns() {
$s0 = $s1 = $s2 = $s3= '';
private function invMixColumns()
{
$s0 = $s1 = $s2 = $s3 = '';
// There are Nb columns
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];
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];
$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[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);
}
}
/** applies an inverse cyclic shift to the last 3 rows of a state matrix.
* @returns void
**/
private function invShiftRows() {
$temp = "";
for ($i=1; $i<4; $i++) {
for ($j=0; $j<self::$Nb; $j++)
$temp[($i+$j)%self::$Nb] = $this->s[$i][$j];
for ($j=0; $j<self::$Nb; $j++)
private function invShiftRows()
{
$temp = '';
for ($i = 1; $i < 4; $i++) {
for ($j = 0; $j < self::$Nb; $j++) {
$temp[($i + $j) % self::$Nb] = $this->s[$i][$j];
}
for ($j = 0; $j < self::$Nb; $j++) {
$this->s[$i][$j] = $temp[$j];
}
}
}
/** applies inverse S-Box substitution to each byte of a state matrix.
* @returns void
**/
private function invSubBytes() {
for ($i=0; $i<4; $i++)
for ($j=0; $j<self::$Nb; $j++)
private function invSubBytes()
{
for ($i = 0; $i < 4; $i++) {
for ($j = 0; $j < self::$Nb; $j++) {
$this->s[$i][$j] = self::$invSBox[$this->s[$i][$j]];
}
}
}
/** mixes each column of a state matrix.
* @returns void
**/
private function mixColumns() {
$s0 = $s1 = $s2 = $s3= '';
private function mixColumns()
{
$s0 = $s1 = $s2 = $s3 = '';
// There are Nb columns
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];
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];
$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);
@ -478,41 +508,49 @@ class AES {
/** applies a cyclic shift to the last 3 rows of a state matrix.
* @returns void
**/
private function shiftRows() {
$temp = "";
for ($i=1; $i<4; $i++) {
for ($j=0; $j<self::$Nb; $j++)
$temp[$j] = $this->s[$i][($j+$i)%self::$Nb];
for ($j=0; $j<self::$Nb; $j++)
private function shiftRows()
{
$temp = '';
for ($i = 1; $i < 4; $i++) {
for ($j = 0; $j < self::$Nb; $j++) {
$temp[$j] = $this->s[$i][($j + $i) % self::$Nb];
}
for ($j = 0; $j < self::$Nb; $j++) {
$this->s[$i][$j] = $temp[$j];
}
}
}
/** applies S-Box substitution to each byte of a state matrix.
* @returns void
**/
private function subBytes() {
for ($i=0; $i<4; $i++) {
for ($j=0; $j<self::$Nb; $j++)
private function subBytes()
{
for ($i = 0; $i < 4; $i++) {
for ($j = 0; $j < self::$Nb; $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
* @returns 8-bit value
**/
private static function mult($a, $b) {
private static function mult($a, $b)
{
$sum = self::$ltable[$a] + self::$ltable[$b];
$sum %= 255;
// Get the antilog
$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.
* @returns 32-bit int
**/
private static function rotWord($w) {
private static function rotWord($w)
{
$temp = $w >> 24; // put the first 8-bits into temp
$w <<= 8; // make room for temp to fill the lower end of the word
self::make32BitWord($w);
@ -526,10 +564,11 @@ class AES {
/** applies S-box substitution to each byte of a 4-byte word.
* @returns 32-bit int
**/
private static function subWord($w) {
private static function subWord($w)
{
$temp = 0;
// loop through 4 bytes of a word
for ($i=0; $i<4; $i++) {
for ($i = 0; $i < 4; $i++) {
$temp = $w >> 24; // put the first 8-bits into temp
// Can't do unsigned shifts, so we need to make this temp positive
$temp = ($temp < 0 ? (256 + $temp) : $temp);
@ -546,9 +585,9 @@ class AES {
/** reduces a 64-bit word to a 32-bit word
* @returns void
**/
private static function make32BitWord(&$w) {
private static function make32BitWord(&$w)
{
// Reduce this 64-bit word to 32-bits on 64-bit machines
$w &= 0x00000000FFFFFFFF;
}
}
?>

108
TL.php
View File

@ -1,11 +1,14 @@
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
require_once ('libpy2php.php');
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once 'libpy2php.php';
$__author__ = 'agrigoryev';
require_once ('os.php');
class TlConstructor {
function __construct($json_dict) {
$this->id = (int)$json_dict['id'];
require_once 'os.php';
class TlConstructor
{
public function __construct($json_dict)
{
$this->id = (int) $json_dict['id'];
$this->type = $json_dict['type'];
$this->predicate = $json_dict['predicate'];
$this->params = [];
@ -13,10 +16,10 @@ class TlConstructor {
if (($param['type'] == 'Vector<long>')) {
$param['type'] = 'Vector t';
$param['subtype'] = 'long';
} else if (($param['type'] == 'vector<%Message>')) {
} elseif (($param['type'] == 'vector<%Message>')) {
$param['type'] = 'vector';
$param['subtype'] = 'message';
} else if (($param['type'] == 'vector<future_salt>')) {
} elseif (($param['type'] == 'vector<future_salt>')) {
$param['type'] = 'vector';
$param['subtype'] = 'future_salt';
} else {
@ -26,22 +29,28 @@ class TlConstructor {
}
}
}
class TlMethod {
function __construct($json_dict) {
$this->id = (int)$json_dict['id'];
class TlMethod
{
public function __construct($json_dict)
{
$this->id = (int) $json_dict['id'];
$this->type = $json_dict['type'];
$this->method = $json_dict['method'];
$this->params = $json_dict['params'];
}
}
class TLObject extends ArrayObject {
function __construct($tl_elem) {
class TLObject extends ArrayObject
{
public function __construct($tl_elem)
{
parent::__construct();
$this->name = $tl_elem->predicate;
}
}
class TL {
function __construct($filename) {
class TL
{
public function __construct($filename)
{
$TL_dict = json_decode(file_get_contents($filename), true);
$this->constructors = $TL_dict['constructors'];
$this->constructor_id = [];
@ -61,83 +70,89 @@ class TL {
}
$this->struct = new \danog\PHP\Struct();
}
function serialize_obj($type_, $kwargs) {
$bytes_io = fopen("php://memory", "rw+b");
if(isset($this->constructor_type[$type_])) {
$tl_constructor = $this->constructor_type[$type_];
}
else
public function serialize_obj($type_, $kwargs)
{
$bytes_io = fopen('php://memory', 'rw+b');
if (isset($this->constructor_type[$type_])) {
$tl_constructor = $this->constructor_type[$type_];
} else {
throw new Exception(sprintf('Could not extract type: %s', $type_));
}
fwrite($bytes_io, $this->struct->pack('<i', $tl_constructor->id));
foreach ($tl_constructor->params as $arg) {
$this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
}
return fread_all($bytes_io);
}
function serialize_method($type_, $kwargs) {
$bytes_io = fopen("php://memory", "rw+b");
if(isset($this->method_name[$type_])) {
$tl_method = $this->method_name[$type_];
}
else
public function serialize_method($type_, $kwargs)
{
$bytes_io = fopen('php://memory', 'rw+b');
if (isset($this->method_name[$type_])) {
$tl_method = $this->method_name[$type_];
} else {
throw new Exception(sprintf('Could not extract type: %s', $type_));
}
fwrite($bytes_io, $this->struct->pack('<i', $tl_method->id));
foreach ($tl_method->params as $arg) {
$this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
}
return fread_all($bytes_io);
}
function serialize_param($bytes_io, $type_, $value) {
public function serialize_param($bytes_io, $type_, $value)
{
if (($type_ == 'int')) {
assert(is_numeric($value));
assert(strlen(decbin($value)) <= 32);
fwrite($bytes_io, $this->struct->pack('<i', $value));
} else if (($type_ == 'long')) {
} elseif (($type_ == 'long')) {
assert(is_numeric($value));
fwrite($bytes_io, $this->struct->pack('<q', $value));
} else if (in_array($type_, ['int128', 'int256'])) {
} elseif (in_array($type_, ['int128', 'int256'])) {
assert(is_string($value));
fwrite($bytes_io, $value);
} else if ($type_ == 'string' || $type_ == 'bytes') {
} elseif ($type_ == 'string' || $type_ == 'bytes') {
$l = len($value);
if (($l < 254)) {
fwrite($bytes_io, $this->struct->pack('<b', $l));
fwrite($bytes_io, $value);
fwrite($bytes_io, pack("@".((-$l - 1) % 4)));
fwrite($bytes_io, pack('@'.((-$l - 1) % 4)));
} else {
fwrite($bytes_io, string2bin('\xfe'));
fwrite($bytes_io, substr($this->struct->pack('<i', $l), null, 3));
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');
if (($type_ == 'int')) {
$x = $this->struct->unpack('<i', fread($bytes_io, 4)) [0];
} else if (($type_ == '#')) {
} elseif (($type_ == '#')) {
$x = $this->struct->unpack('<I', fread($bytes_io, 4)) [0];
} else if (($type_ == 'long')) {
} elseif (($type_ == 'long')) {
$x = $this->struct->unpack('<q', fread($bytes_io, 8)) [0];
} else if (($type_ == 'double')) {
} elseif (($type_ == 'double')) {
$x = $this->struct->unpack('<d', fread($bytes_io, 8)) [0];
} else if (($type_ == 'int128')) {
} elseif (($type_ == 'int128')) {
$x = fread($bytes_io, 16);
} else if (($type_ == 'int256')) {
} elseif (($type_ == 'int256')) {
$x = fread($bytes_io, 32);
} else if (($type_ == 'string') || ($type_ == 'bytes')) {
} elseif (($type_ == 'string') || ($type_ == 'bytes')) {
$l = $this->struct->unpack('<C', fread($bytes_io, 1)) [0];
assert($l <= 254);
if (($l == 254)) {
$long_len = $this->struct->unpack('<I', fread($bytes_io, 3) . string2bin('\x00')) [0];
$long_len = $this->struct->unpack('<I', fread($bytes_io, 3).string2bin('\x00')) [0];
$x = fread($bytes_io, $long_len);
fread($bytes_io, (-$long_len % 4));
} else {
@ -145,19 +160,19 @@ class TL {
fread($bytes_io, (($l + 1) % 4));
}
assert(is_string($x));
} else if (($type_ == 'vector')) {
} elseif (($type_ == 'vector')) {
assert($subtype != null);
$count = $this->struct->unpack('<l', substr($bytes_io, 4)) [0];
$x = [];
foreach( pyjslib_range($count) as $i ) {
foreach (pyjslib_range($count) as $i) {
$x[] = deserialize($bytes_io, $subtype);
}
} else {
if(isset($this->constructor_type[$type_])) {
if (isset($this->constructor_type[$type_])) {
$tl_elem = $this->constructor_type[$type_];
} else {
$i = $this->struct->unpack('<i', fread($bytes_io, 4)) [0];
if(isset($this->constructor_id[$i])) {
if (isset($this->constructor_id[$i])) {
$tl_elem = $this->constructor_id[$i];
} else {
throw new Exception(sprintf('Could not extract type: %s', $type_));
@ -174,6 +189,7 @@ class TL {
}
}
}
return $x;
}
}

View File

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

View File

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

View File

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

View File

@ -1,43 +1,51 @@
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
require_once ('libpy2php.php');
require_once ('os.php');
class File {
function __construct($path) {
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once 'libpy2php.php';
require_once 'os.php';
class file
{
public function __construct($path)
{
$this->_path = $path;
}
/**
* 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.
}
/**
* 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))) {
return '';
}
// py2php.fixme "with" unsupported.
}
}
/**
* tries to open with os default viewer
* tries to open with os default viewer.
*/
function open() {
new call((os::name == 'nt') ? 'cmd /c start "" "' . $this->_path . '"' : [platform::startswith('darwin') ? 'open' : 'xdg-open', $this->_path]);
public function open()
{
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 {
os::remove($this->_path);
}
catch(FileNotFoundError $e) {
} catch (FileNotFoundError $e) {
}
}
}

View File

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

View File

@ -1,280 +1,373 @@
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
require_once ('libpy2php.php');
require_once ('os.php');
class TelepyShell {
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once 'libpy2php.php';
require_once 'os.php';
class TelepyShell
{
public $intro = 'Welcome to telepy interactive shell. Type help or ? for help.
';
public $prompt = '>';
function preloop() {
require_once ('classes/telepy.php');
public function preloop()
{
require_once 'classes/telepy.php';
$this->_telepy = new Telepy();
}
function precmd($line) {
public function precmd($line)
{
$line = $line->lstrip();
$blank_pos = $line->find(' ');
if (($blank_pos < 0)) {
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);
}
function complete($text, $state) {
public function complete($text, $state)
{
$this->super()->complete($text, $state);
pyjslib_printnl('completing');
}
/**
* shell <command-line>
* 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());
}
/**
* 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>
* 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>
* 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>
* 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>
* 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 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* prints info about chat
* prints info about chat.
*/
function do_chat_info($arg) {
public function do_chat_info($arg)
{
$arg = $arg->split();
if ((count($arg) == 1)) {
pyjslib_printnl(['chat_info called with ', $arg[0]]);
}
}
/**
* 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);
}
/**
* 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>
* rename chat room
* rename chat room.
*/
function do_chat_rename($arg) {
public function do_chat_rename($arg)
{
$arg = $arg->split();
}
/**
* 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([$user1, $user2, $user3]);
}
/**
* chat_set_photo <chat> <photo-file-name>
* 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>
* searches pattern in messages with peer
* searches pattern in messages with peer.
*/
function do_search($pattern) {
public function do_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>
* 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>
* 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>
* 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>
* 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>
* prints info about user
* prints info about user.
*/
function do_user_info($user) {
public function do_user_info($user)
{
}
/**
* 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 == '')) {
pyjslib_printnl('no peer have specified');
return;
}
$args = $peer->split();
if (!in_array(count($args), [1, 2])) {
pyjslib_printnl(['not appropriate number of arguments : ', $peer]);
return;
}
if ((count($args) == 2)) {
@ -286,54 +379,70 @@ class TelepyShell {
pyjslib_printnl($peer);
pyjslib_printnl($limit);
}
/**
* 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
* 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
* 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
* just for debugging
* just for debugging.
*/
function do_stats($ignored) {
public function do_stats($ignored)
{
}
/**
* 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>
* 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 without waiting for query ends
* quit without waiting for query ends.
*/
function do_quit_force($ignored) {
public function do_quit_force($ignored)
{
return true;
}
/**
* 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;
}
}

View File

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

View File

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

View File

@ -1,14 +1,20 @@
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
require_once ('libpy2php.php');
require_once ('AES.class.php');
class crypt {
function ige_encrypt($message, $key, $iv) {
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once 'libpy2php.php';
require_once 'AES.class.php';
class crypt
{
public function ige_encrypt($message, $key, $iv)
{
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');
}
/**
* Given a key, given an iv, and message
* do whatever operation asked in the operation field.
@ -17,21 +23,22 @@ class crypt {
* message must be a multiple by 16 bytes (for division in 16 byte blocks)
* key must be 32 byte
* 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);
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)');
}
if ((len($iv) != 32)) {
throw new Exception('iv must be 32 bytes long (was ' . len($iv) . ' bytes)');
throw new Exception('iv must be 32 bytes long (was '.len($iv).' bytes)');
}
$cipher = new AES($key);
$cipher = $cipher->encrypt($iv);
$blocksize = $cipher->block_size;
if ((len($message) % $blocksize) != 0) {
throw new Exception('message must be a multiple of 16 bytes (try adding ' . (16 - (count($message) % 16)) . ' bytes of padding)');
throw new Exception('message must be a multiple of 16 bytes (try adding '.(16 - (count($message) % 16)).' bytes of padding)');
}
$ivp = substr($iv, 0, $blocksize - 0);
$ivp2 = substr($iv, $blocksize, null);
@ -44,7 +51,7 @@ class crypt {
$outdata = strxor($decrypt_xored, $ivp);
$ivp = $indata;
$ivp2 = $outdata;
} else if (($operation == 'encrypt')) {
} elseif (($operation == 'encrypt')) {
$xored = strxor($indata, $ivp);
$encrypt_xored = $cipher->encrypt($xored);
$outdata = strxor($encrypt_xored, $ivp2);
@ -55,6 +62,7 @@ class crypt {
}
$ciphered .= $outdata;
}
return $ciphered;
}
}

View File

@ -1,21 +1,21 @@
<?php
# Copyright 2006 James Tauber and contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
// Copyright 2006 James Tauber and contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// 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
* thrown instead of standard php error handling.
@ -26,175 +26,182 @@
* 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
* 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();
# iteration from Bob Ippolito's Iteration in JavaScript
# 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) {
// iteration from Bob Ippolito's Iteration in JavaScript
// 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)
{
return is_object($a);
}
function pyjslib_isFunction($a) {
function pyjslib_isFunction($a)
{
return is_function($a);
}
function pyjslib_isString($a) {
function pyjslib_isString($a)
{
return is_string($a);
}
function pyjslib_isNull($a) {
function pyjslib_isNull($a)
{
return is_null($a);
}
function pyjslib_isArray($a) {
function pyjslib_isArray($a)
{
return is_array($a);
}
function pyjslib_isUndefined($a) {
function pyjslib_isUndefined($a)
{
return !isset($a);
}
function pyjslib_isIteratable($a) {
function pyjslib_isIteratable($a)
{
return $a instanceof Traversable;
}
function pyjslib_isNumber($a) {
function pyjslib_isNumber($a)
{
return is_numeric($a);
}
function pyjslib_int($a) {
return (int)$a;
function pyjslib_int($a)
{
return (int) $a;
}
function pyjslib_str($val) {
return (string)$val;
function pyjslib_str($val)
{
return (string) $val;
}
function pyjslib_del_slice(&$list, $from, $to, $step=1) {
if( $from <= 0 ) {
function pyjslib_del_slice(&$list, $from, $to, $step = 1)
{
if ($from <= 0) {
$from = 0;
}
if( $to === null ) {
if ($to === null) {
$to = count($list);
}
if( $step <= 0 ) {
if ($step <= 0) {
$step = 1;
}
for( $i = $from; $i < $to; $i += $step ) {
unset( $list[$i]);
for ($i = $from; $i < $to; $i += $step) {
unset($list[$i]);
}
}
function pyjslib_array_slice($list, $from, $to, $step=1) {
function pyjslib_array_slice($list, $from, $to, $step = 1)
{
$newlist = [];
if( $from <= 0 ) {
if ($from <= 0) {
$from = 0;
}
if( $to === null ) {
if ($to === null) {
$to = count($list);
}
if( $step <= 0 ) {
if ($step <= 0) {
$step = 1;
}
for( $i = $from; $i < $to; $i += $step ) {
for ($i = $from; $i < $to; $i += $step) {
$newlist[] = $list[$i];
}
return $newlist;
}
# taken from mochikit: range( [start,] stop[, step] )
function pyjslib_range($start, $stop = null, $step = 1) {
if( $stop === null ) {
// taken from mochikit: range( [start,] stop[, step] )
function pyjslib_range($start, $stop = null, $step = 1)
{
if ($stop === null) {
$stop = $start;
$start = 0;
}
if( $stop <= $start && $step < 0 ) {
$arr = range( $stop, $start, -$step );
array_pop( $arr );
return array_reverse( $arr, false );
if ($stop <= $start && $step < 0) {
$arr = range($stop, $start, -$step);
array_pop($arr);
return array_reverse($arr, false);
}
$arr = range( $start, $stop, $step );
array_pop( $arr );
$arr = range($start, $stop, $step);
array_pop($arr);
return $arr;
}
function pyjslib_filter($callback, $iterable) {
function pyjslib_filter($callback, $iterable)
{
$a = [];
foreach( $iterable as $item ) {
if( call_user_func( $callback, $item ) ) {
foreach ($iterable as $item) {
if (call_user_func($callback, $item)) {
$a[] = $item;
}
}
return $a;
}
function pyjslib_globals() {
function pyjslib_globals()
{
return $GLOBALS;
}
function pyjslib_map($callable) {
function pyjslib_map($callable)
{
$done = false;
$call_cnt = 0;
$results = [];
$params = func_get_args();
array_shift( $params );
array_shift($params);
while( !$done ) {
while (!$done) {
$func_args = [];
$found = false;
for( $i = 0; $i < count($params); $i ++ ) {
for ($i = 0; $i < count($params); $i++) {
$func_args[] = @$params[$i][$call_cnt];
if( count($params[$i]) > $call_cnt + 1 ) {
if (count($params[$i]) > $call_cnt + 1) {
$found = true;
}
}
if( !$found ) {
if (!$found) {
$done = true;
}
$results[] = call_user_func_array($callable, $func_args);
$call_cnt ++;
$call_cnt++;
}
return $results;
}
function pyjslib_zip() {
function pyjslib_zip()
{
$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
$result = array();
foreach ($params[0] as $item){
$result[] = array($item);
};
$result = [];
foreach ($params[0] as $item) {
$result[] = [$item];
}
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));
return array_slice($result, 0, $length);
}
@ -203,82 +210,83 @@ function pyjslib_is_assoc($arr)
return array_keys($arr) !== range(0, count($arr) - 1);
}
function pyjslib_dict($arg=null) {
if( $arg === null ) {
function pyjslib_dict($arg = null)
{
if ($arg === null) {
return [];
}
if( pyjslib_is_assoc( $arg )) {
if (pyjslib_is_assoc($arg)) {
return $arg;
}
$dict = [];
foreach( $arg as $a ) {
if( count($a) == 2 ) {
foreach ($arg as $a) {
if (count($a) == 2) {
$dict[$a[0]] = $a[1];
}
}
return $dict;
}
function pyjslib_printWorker($objs, $nl, $multi_arg, $depth=1) {
function pyjslib_printWorker($objs, $nl, $multi_arg, $depth = 1)
{
$buf = '';
if( is_array( $objs ) && $multi_arg && $depth == 1) {
if (is_array($objs) && $multi_arg && $depth == 1) {
$cnt = 0;
foreach( $objs as $obj ) {
if( $cnt ++ > 0 ) {
$buf .= " ";
foreach ($objs as $obj) {
if ($cnt++ > 0) {
$buf .= ' ';
}
$buf .= pyjslib_printWorker( $obj, $nl, $multi_arg, $depth + 1 );
$buf .= pyjslib_printWorker($obj, $nl, $multi_arg, $depth + 1);
}
}
else if( is_bool( $objs )) {
$buf = $objs ? "True" : "False";
}
else if( is_null( $objs )) {
} elseif (is_bool($objs)) {
$buf = $objs ? 'True' : 'False';
} elseif (is_null($objs)) {
$buf = 'None';
}
else if( is_float( $objs )) {
$buf = (int)$objs;
}
else if( is_string( $objs ) && ($multi_arg && $depth > 2 || (!$multi_arg && $depth > 1) ) ) {
} elseif (is_float($objs)) {
$buf = (int) $objs;
} elseif (is_string($objs) && ($multi_arg && $depth > 2 || (!$multi_arg && $depth > 1))) {
$buf = "'$objs'";
}
elseif( is_array( $objs )) {
} elseif (is_array($objs)) {
$buf = '[';
$cnt = 0;
foreach( $objs as $obj ) {
foreach ($objs as $obj) {
$val = pyjslib_printWorker($obj, $nl, false, $depth + 1);
if( $cnt ++ > 0 ) {
if ($cnt++ > 0) {
$buf .= ', ';
}
$buf .= $val;
}
$buf .= "]";
$buf .= ']';
// $buf = '[' . implode( ", ", $objs ) . ']';
}
else {
} else {
$buf = $objs;
}
if( $depth == 1 && (!strlen($buf) || $buf[strlen($buf)-1] != "\n") ) {
$buf .= $nl ? "\n" : " ";
if ($depth == 1 && (!strlen($buf) || $buf[strlen($buf) - 1] != "\n")) {
$buf .= $nl ? "\n" : ' ';
}
return $buf;
}
function pyjslib_repr($obj) {
function pyjslib_repr($obj)
{
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);
}
function pyjslib_printnl($objs, $multi_arg=false) {
function pyjslib_printnl($objs, $multi_arg = false)
{
echo pyjslib_printWorker($objs, true, $multi_arg);
}
function py2php_kwargs_function_call($funcname, $ordered, $named) {
if( $funcname == 'array' || $funcname == 'pyjslib_dict' ) {
function py2php_kwargs_function_call($funcname, $ordered, $named)
{
if ($funcname == 'array' || $funcname == 'pyjslib_dict') {
return $named;
}
@ -286,58 +294,62 @@ function py2php_kwargs_function_call($funcname, $ordered, $named) {
$count = 1;
$refFunc = new ReflectionFunction($funcname);
foreach( $refFunc->getParameters() as $param ){
if( $param->isVariadic() ) {
$ordered[$count-1] = $named;
foreach ($refFunc->getParameters() as $param) {
if ($param->isVariadic()) {
$ordered[$count - 1] = $named;
break;
}
//invokes ReflectionParameter::__toString
if( $count > $num_ordered ) {
if ($count > $num_ordered) {
$name = $param->name;
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
$ordered[] = @$named[$name] ?: $default;
}
$count ++;
$count++;
}
//var_dump($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);
$count = 1;
$refFunc = new ReflectionMethod($obj, $method);
foreach( $refFunc->getParameters() as $param ){
foreach ($refFunc->getParameters() as $param) {
//invokes ReflectionParameter::__toString
if( $count > $num_ordered ) {
if ($count > $num_ordered) {
$name = $param->name;
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
$ordered[] = @$named[$name] ?: $default;
}
$count ++;
$count++;
}
$callable = [$obj, $method];
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 ) {
return new pyjslib_file( $name, $mode, $buffering );
function pyjslib_open($name, $mode = 'r', $buffering = null)
{
return new pyjslib_file($name, $mode, $buffering);
}
class pyjslib_file implements Iterator {
class pyjslib_file implements Iterator
{
private $fh = false;
private $current_line = null;
@ -349,138 +361,160 @@ class pyjslib_file implements Iterator {
public $newlines = null;
public $softspace = false;
function __construct($name_or_fd, $mode="r", $buffering=null) {
if( is_resource($name_or_fd) ) {
public function __construct($name_or_fd, $mode = 'r', $buffering = null)
{
if (is_resource($name_or_fd)) {
$this->fh = $name_or_fd;
$this->closed = false;
$meta = stream_get_meta_data( $name_or_df );
$meta = stream_get_meta_data($name_or_df);
$this->mode = $meta['mode'];
return;
}
$name = $name_or_fd;
try {
$this->fh = fopen($name, $mode);
if( !$this->fh ) {
if (!$this->fh) {
throw new Exception("Could not open $name");
}
$this->closed = false;
$this->mode = $mode;
}
catch( Exception $e ) {
throw new IOError( $e->getMessage(), $e->getCode() );
} catch (Exception $e) {
throw new IOError($e->getMessage(), $e->getCode());
}
}
function close() {
if( $this->fh ) {
fclose( $this->fh );
public function close()
{
if ($this->fh) {
fclose($this->fh);
$this->fh = null;
$this->closed = true;
}
}
function flush() {
if( !$this->fh ) {
throw new ValueError("File is closed.");
public function flush()
{
if (!$this->fh) {
throw new ValueError('File is closed.');
}
fflush( $this->fh );
fflush($this->fh);
}
function fileno() {
if( !$this->fh ) {
throw new ValueError("File is closed.");
public function fileno()
{
if (!$this->fh) {
throw new ValueError('File is closed.');
}
return $this->fh;
}
function isatty() {
if( !$this->fh ) {
throw new ValueError("File is closed.");
public function isatty()
{
if (!$this->fh) {
throw new ValueError('File is closed.');
}
return posix_isatty( $this->fh );
return posix_isatty($this->fh);
}
/* ---
* Begin PHP Iterator implementation
* ---
*/
function rewind() {
fseek( $this->fh, 0 );
public function rewind()
{
fseek($this->fh, 0);
$this->line = 0;
}
function current() {
if( !$this->current_line ) {
$this->current_line = fgets( $this->fh );
public function current()
{
if (!$this->current_line) {
$this->current_line = fgets($this->fh);
}
return $this->current_line;
}
function key() {
public function key()
{
return $this->line;
}
function next() {
public function next()
{
$this->current(); // ensure current line has been retrieved.
$this->current_line = fgets( $this->fh );
$this->line ++;
$this->current_line = fgets($this->fh);
$this->line++;
return $this->current_line;
}
function valid() {
return $this->fh != false && !feof( $this->fh );
public function valid()
{
return $this->fh != false && !feof($this->fh);
}
/* ---
* End PHP Iterator implementation
* ---
*/
function read($size=null) {
if( $size !== null) {
return fread( $this->fh, $size);
}
return stream_get_contents( $this->fh );
public function read($size = null)
{
if ($size !== null) {
return fread($this->fh, $size);
}
function readline($size=null) {
return fgets( $this->fh, $size );
return stream_get_contents($this->fh);
}
function readlines($sizehint=null) {
public function readline($size = null)
{
return fgets($this->fh, $size);
}
public function readlines($sizehint = null)
{
$len = 0;
$lines = array();
while( $line = fgets( $this->fh ) ) {
$len += strlen( $line );
$lines = [];
while ($line = fgets($this->fh)) {
$len += strlen($line);
$lines[] = $line;
if( $sizehint && $len >= $sizehint ) {
if ($sizehint && $len >= $sizehint) {
break;
}
}
return $lines;
}
function seek($offset, $whence=SEEK_SET) {
return fseek( $this->fh, $offset, $whence);
public function seek($offset, $whence = SEEK_SET)
{
return fseek($this->fh, $offset, $whence);
}
function tell() {
public function tell()
{
return ftell($this->fh);
}
function truncate( $size ) {
$rc = ftruncate( $this->fh, $size );
public function truncate($size)
{
$rc = ftruncate($this->fh, $size);
}
function write( $str ) {
fwrite( $this->fh, $str );
public function write($str)
{
fwrite($this->fh, $str);
}
function writelines($sequence) {
foreach($sequence as $line) {
$this->write( $line );
public function writelines($sequence)
{
foreach ($sequence as $line) {
$this->write($line);
}
}
}

View File

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

View File

@ -1,214 +1,251 @@
<?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;
static function abspath($path) {
public static function abspath($path)
{
return self::normpath(self::join(getcwd(), $path));
}
static function basename($path) {
public static function basename($path)
{
// is this right?
return basename($path);
}
static function commonprefix($list) {
public static function commonprefix($list)
{
$pl = 0; // common prefix length
$n = count($list);
$l = strlen($list[0]);
while ($pl < $l) {
$c = $list[0][$pl];
for ($i=1; $i<$n; $i++) {
for ($i = 1; $i < $n; $i++) {
if ($list[$i][$pl] !== $c) {
break 2;
}
}
$pl++;
}
return substr($list[0], 0, $pl);
}
static function dirname($path) {
public static function dirname($path)
{
return dirname($path);
}
static function exists($path) {
public static function exists($path)
{
return file_exists($path);
}
static function lexists($path) {
public static function lexists($path)
{
$rc = file_exists($path);
if( !$rc && is_link($path) ) {
if (!$rc && is_link($path)) {
return true;
}
return $rc;
}
static function expanduser($path) {
if( strpos($path, '~') !== false) {
public static function expanduser($path)
{
if (strpos($path, '~') !== false) {
$info = posix_getpwuid(posix_getuid());
$path = str_replace('~', $info['dir'], $path);
}
return $path;
}
static function expandvars($path) {
public static function expandvars($path)
{
$env = count($_ENV) ?: $_SERVER;
$map = array();
foreach( $env as $k => $v ) {
if( !is_scalar( $v )) {
$map = [];
foreach ($env as $k => $v) {
if (!is_scalar($v)) {
continue;
}
$map['$' . $k] = $v;
$map['${' . $k . '}'] = $v;
$map['$'.$k] = $v;
$map['${'.$k.'}'] = $v;
}
return strtr($path, $map);
}
static function getatime($path) {
public static function getatime($path)
{
try {
$rc = fileatime($path);
return $rc;
}
catch( Exception $e ) {
} catch (Exception $e) {
throw new OSError($e->getMessage, $e->getCode());
}
}
static function getmtime($path) {
public static function getmtime($path)
{
try {
$rc = filemtime($path);
return $rc;
}
catch( Exception $e ) {
} catch (Exception $e) {
throw new OSError($e->getMessage, $e->getCode());
}
}
static function getctime($path) {
public static function getctime($path)
{
try {
$rc = filectime($path);
return $rc;
}
catch( Exception $e ) {
} catch (Exception $e) {
throw new OSError($e->getMessage, $e->getCode());
}
}
static function getsize($path) {
public static function getsize($path)
{
try {
$rc = filesize($path);
return $rc;
}
catch( Exception $e ) {
} catch (Exception $e) {
throw new OSError($e->getMessage, $e->getCode());
}
}
static function isabs($path) {
public static function isabs($path)
{
// fixme: implement check for windows.
return $path[0] == '/';
}
static function isfile($path) {
public static function isfile($path)
{
return is_file($path);
}
static function isdir($path) {
public static function isdir($path)
{
return is_dir($path);
}
static function islink($path) {
public static function islink($path)
{
return is_link($path);
}
static function ismount($path) {
public static function ismount($path)
{
self::_unimplemented();
}
static function split($path) {
public static function split($path)
{
$parts = explode(DIRECTORY_SEPARATOR, $path);
$first = implode(DIRECTORY_SEPARATOR, array_slice($parts, 0, count($parts)-1 ));
$last = $parts[count($parts)-1];
return array($first, $last);
$first = implode(DIRECTORY_SEPARATOR, array_slice($parts, 0, count($parts) - 1));
$last = $parts[count($parts) - 1];
return [$first, $last];
}
static function join($path, ...$paths) {
public static function join($path, ...$paths)
{
$buf = rtrim($path, '/');
foreach( $paths as $p ) {
foreach ($paths as $p) {
$i = 0;
$p = trim( $p, '/');
$buf .= DIRECTORY_SEPARATOR . $p;
$p = trim($p, '/');
$buf .= DIRECTORY_SEPARATOR.$p;
}
return $buf;
}
static function normcase($path) {
public static function normcase($path)
{
// fixme: different behavior on windows.
return $path;
}
static function normpath($path) {
public static function normpath($path)
{
return realpath($path);
}
static function realpath($path) {
public static function realpath($path)
{
return realpath($path);
}
static function relpath($path, $start) {
public static function relpath($path, $start)
{
self::_unimplemented();
}
static function samefile($path1, $path2) {
public static function samefile($path1, $path2)
{
return fileinode($path1) == fileinode($path2);
}
static function sameopenfile($fd1, $fd2) {
$s1 = fstat( $fd1 );
$s2 = fstat( $fd2 );
public static function sameopenfile($fd1, $fd2)
{
$s1 = fstat($fd1);
$s2 = fstat($fd2);
return $s1['ino'] == $s2['ino'];
}
static function samestat($stat1, $stat2) {
public static function samestat($stat1, $stat2)
{
return $stat1 == $stat2;
}
static function splitdrive($path) {
public static function splitdrive($path)
{
//fixme: implement windows case.
return array('', $path);
return ['', $path];
}
static function splitext($path) {
public static function splitext($path)
{
$first = $path;
$second = '';
$pos = strrpos( $path, '.');
if( $pos !== false ) {
$pos = strrpos($path, '.');
if ($pos !== false) {
$first = substr($path, 0, $pos);
$second = substr($path, $pos);
}
return array($first, $second);
return [$first, $second];
}
static function splitunc($path) {
public static function splitunc($path)
{
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()
self::_unimplemented();
}
private static function _unimplemented() {
throw new Exception( "Unimplemented. Please consider submitting a patch to py2php project on github.");
private static function _unimplemented()
{
throw new Exception('Unimplemented. Please consider submitting a patch to py2php project on github.');
}
}

View File

@ -7,18 +7,18 @@
* It is called in this file; the parent php file(s) should use require_once and do
* 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.
error_reporting( E_ALL | E_STRICT );
error_reporting(E_ALL | E_STRICT);
restore_strict_error_handler();
restore_strict_exception_handler();
// register_shutdown_function should only be called once per process to avoid dups.
static $called = false;
if( !$called ) {
register_shutdown_function( "shutdown_handler" );
if (!$called) {
register_shutdown_function('shutdown_handler');
$called = true;
}
}
@ -28,19 +28,20 @@ function init_strict_mode() {
* eg by a 3rd party lib. Any error handlers that were registered after
* ours are removed.
*/
function restore_strict_error_handler() {
$e_handler_name = function() {
function restore_strict_error_handler()
{
$e_handler_name = function () {
$name = set_error_handler('restore_strict_error_handler'); // will never be used.
restore_error_handler();
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();
}
if( !$e_handler_name() ) {
set_error_handler( '_global_error_handler' );
if (!$e_handler_name()) {
set_error_handler('_global_error_handler');
}
}
@ -49,19 +50,20 @@ function restore_strict_error_handler() {
* eg by a 3rd party lib. Any error handlers that were registered after
* ours are removed.
*/
function restore_strict_exception_handler() {
$exc_handler_name = function() {
function restore_strict_exception_handler()
{
$exc_handler_name = function () {
$name = set_exception_handler('restore_strict_exception_handler'); // will never be used.
restore_exception_handler();
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();
}
if( !$exc_handler_name() ) {
set_exception_handler( '_global_exception_handler' );
if (!$exc_handler_name()) {
set_exception_handler('_global_exception_handler');
}
}
@ -72,7 +74,8 @@ function restore_strict_exception_handler() {
*
* 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
* error_reporting() settings will have no effect and your error handler will
@ -80,7 +83,7 @@ function _global_error_handler($errno, $errstr, $errfile, $errline ) {
* error_reporting and act appropriately. Of particular note is that this value will
* be 0 if the statement that caused the error was prepended by the @ error-control operator.
*/
if( !error_reporting() ) {
if (!error_reporting()) {
return;
}
@ -91,44 +94,45 @@ 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.
*/
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() );
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() );
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());
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());
}
echo $msg;
// error_log( $msg );
strict_mode_mail_admin( 'Uncaught exception!', $msg );
strict_mode_mail_admin('Uncaught exception!', $msg);
echo "\n\nNow exiting. Please report this problem to the software author\n\n";
exit(1);
}
/**
* 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();
$ignore = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_DEPRECATED | E_USER_DEPRECATED;
if ( $error && ($error['type'] & $ignore) == 0) {
if ($error && ($error['type'] & $ignore) == 0) {
// error keys: type, file, line, message
$msg = "Ouch! Encountered PHP Fatal Error. Shutting down.\n" . print_r( $error, true );
$msg = "Ouch! Encountered PHP Fatal Error. Shutting down.\n".print_r($error, true);
echo $msg;
strict_mode_mail_admin( 'PHP Fatal Error!', $msg );
strict_mode_mail_admin('PHP Fatal Error!', $msg);
}
}
/**
* email admin if defined
* email admin if defined.
*/
function strict_mode_mail_admin( $subject, $msg ) {
$subject = sprintf( '[%s] [%s] %s [pid: %s]', gethostname(), basename($_SERVER['PHP_SELF']), $subject, getmypid() );
if( defined('ALERTS_MAIL_TO') ) {
mail( ALERTS_MAIL_TO, $subject, $msg );
}
else {
function strict_mode_mail_admin($subject, $msg)
{
$subject = sprintf('[%s] [%s] %s [pid: %s]', gethostname(), basename($_SERVER['PHP_SELF']), $subject, getmypid());
if (defined('ALERTS_MAIL_TO')) {
mail(ALERTS_MAIL_TO, $subject, $msg);
} else {
echo "\nWARNING: ALERTS_MAIL_TO not defined in environment. alert not sent with subject: $subject\n";
}
}

View File

@ -1,25 +1,30 @@
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
require_once ('libpy2php.php');
require_once ('os_path.php');
require_once ('crypt.php');
require_once ('prime.php');
require_once ('TL.php');
require_once ('Struct.php');
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once 'libpy2php.php';
require_once 'os_path.php';
require_once 'crypt.php';
require_once 'prime.php';
require_once 'TL.php';
require_once 'Struct.php';
/**
* Function to get hex crc32
* :param data: Data to encode
* :param data: Data to encode.
*/
function newcrc32($data) {
return hexdec(hash("crc32b", $data));
function newcrc32($data)
{
return hexdec(hash('crc32b', $data));
}
/**
* 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.
*
@ -40,22 +45,27 @@ function hex_dump($what) { var_dump(bin2hex($what)); };
/**
* 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);
$symbols_in_one_line = 8;
$n = floor(len($bs) / $symbols_in_one_line);
$i = 0;
foreach (pyjslib_range($n) as $i) {
echo $i * $symbols_in_one_line . ' | ' . join(' ',
array_map(function($el) { return bin2hex($el); }, array_slice($bs,$i*$symbols_in_one_line, ($i+1)*$symbols_in_one_line))
) . PHP_EOL;
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))
).PHP_EOL;
}
if (!(len($bs) % $symbols_in_one_line == 0)) {
echo ($i + 1) * $symbols_in_one_line . ' | ' . join(' ',
array_map(function($el) { return bin2hex($el); }, array_slice($bs, ($i+1)*$symbols_in_one_line))
) . PHP_EOL;
echo($i + 1) * $symbols_in_one_line.' | '.implode(' ',
array_map(function ($el) {
return bin2hex($el);
}, array_slice($bs, ($i + 1) * $symbols_in_one_line))
).PHP_EOL;
}
}
/**
@ -63,7 +73,8 @@ function vis($bs) {
* Convert a byte string to a long integer.
* This is (essentially) the inverse of long_to_bytes().
*/
function bytes_to_long($s) {
function bytes_to_long($s)
{
$acc = 0;
$length = strlen($s);
if (($length % 4)) {
@ -71,23 +82,28 @@ function bytes_to_long($s) {
$s = (($b('') * $extra) + $s);
$length = ($length + $extra);
}
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]);
}
return $acc;
}
function fread_all($handle) {
function fread_all($handle)
{
$pos = ftell($handle);
fseek($handle, 0);
$content = fread($handle, fstat($handle)["size"]);
$content = fread($handle, fstat($handle)['size']);
fseek($handle, $pos);
return $content;
}
function fopen_and_write($filename, $mode, $data) {
function fopen_and_write($filename, $mode, $data)
{
$handle = fopen($filename, $mode);
fwrite($handle, $data);
rewind($handle);
return $handle;
}
/**
@ -97,14 +113,15 @@ function fopen_and_write($filename, $mode, $data) {
* byte string with binary zeros so that the length is a multiple of
* blocksize.
*/
function long_to_bytes($n,$blocksize=0) {
function long_to_bytes($n, $blocksize = 0)
{
$s = $b('');
$n = long($n);
while (($n > 0)) {
$s = ($this->struct->pack('I', $n & 4294967295) + $s);
$n = $n >> 32;
}
foreach( pyjslib_range(strlen($s)) as $i ) {
foreach (pyjslib_range(strlen($s)) as $i) {
if (($s[$i] != $b('')[0])) {
break;
}
@ -113,24 +130,31 @@ function long_to_bytes($n,$blocksize=0) {
if (($blocksize > 0) && (strlen($s) % $blocksize)) {
$s = ((($blocksize - (strlen($s) % $blocksize)) * $b('')) + $s);
}
return $s;
}
function string2bin($string) {
function string2bin($string)
{
$res = null;
foreach(explode('\\', $string) as $s) {
if($s != null && $s[0] == "x") {
foreach (explode('\\', $string) as $s) {
if ($s != null && $s[0] == 'x') {
$res .= hex2bin(substr($s, 1));
}
}
return $res;
}
/**
* Manages TCP Transport. encryption and message frames
* Manages TCP Transport. encryption and message frames.
*/
class Session {
function __construct($ip, $port, $auth_key = null, $server_salt = null) {
$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.");
class Session
{
public function __construct($ip, $port, $auth_key = null, $server_salt = null)
{
$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->timedelta = 0;
$this->session_id = random_bytes(8);
@ -141,59 +165,65 @@ class Session {
$this->AUTH_MAX_RETRY = 5;
$this->struct = new \danog\PHP\Struct();
try {
$this->tl = new TL("https://core.telegram.org/schema/mtproto-json");
} catch(Exception $e){
$this->tl = new TL(__DIR__ . '/TL_schema.JSON');
$this->tl = new TL('https://core.telegram.org/schema/mtproto-json');
} catch (Exception $e) {
$this->tl = new TL(__DIR__.'/TL_schema.JSON');
}
}
function __destruct() {
public function __destruct()
{
fclose($this->sock);
}
/**
* 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) {
$message_id = $this->struct->pack('<Q', (int)((time() + $this->timedelta) * pow(2, 30)) * 4);
public function send_message($message_data)
{
$message_id = $this->struct->pack('<Q', (int) ((time() + $this->timedelta) * pow(2, 30)) * 4);
if (($this->auth_key == null) || ($this->server_salt == null)) {
$message = string2bin('\x00\x00\x00\x00\x00\x00\x00\x00') . $message_id . $this->struct->pack('<I', strlen($message_data)) . $message_data;
$message = string2bin('\x00\x00\x00\x00\x00\x00\x00\x00').$message_id.$this->struct->pack('<I', strlen($message_data)).$message_data;
} else {
$encrypted_data =
$this->server_salt . $this->session_id . $message_id . $this->struct->pack('<II', $this->number, strlen($message_data)) . $message_data;
$this->server_salt.$this->session_id.$message_id.$this->struct->pack('<II', $this->number, strlen($message_data)).$message_data;
$message_key = substr(sha1($encrypted_data, true), -16, null);
$padding = random_bytes((-strlen($encrypted_data) % 16));
echo strlen($encrypted_data . $padding) . PHP_EOL;
echo strlen($encrypted_data.$padding).PHP_EOL;
list($aes_key, $aes_iv) = $this->aes_calculate($message_key);
$message = $this->auth_key_id . $message_key . crypt::ige_encrypt($encrypted_data . $padding, $aes_key, $aes_iv);
$message = $this->auth_key_id.$message_key.crypt::ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv);
}
$step1 = $this->struct->pack('<II', (strlen($message) + 12), $this->number) . $message;
$step2 = $step1 . $this->struct->pack('<I', newcrc32($step1));
$step1 = $this->struct->pack('<II', (strlen($message) + 12), $this->number).$message;
$step2 = $step1.$this->struct->pack('<I', newcrc32($step1));
fwrite($this->sock, $step2);
$this->number += 1;
}
/**
* Reading socket and receiving message from server. Check the CRC32.
*/
function recv_message() {
public function recv_message()
{
$packet_length_data = fread($this->sock, 4);
if (len($packet_length_data) < 4) {
throw new Exception('Nothing in the socket!');
}
$packet_length = $this->struct->unpack('<I', $packet_length_data)[1];
$packet = fread($this->sock, ($packet_length - 4));
if (!(newcrc32($packet_length_data . substr($packet, 0, -4 - 0)) == $this->struct->unpack('<I', substr($packet, -4, null))[1])) {
if (!(newcrc32($packet_length_data.substr($packet, 0, -4 - 0)) == $this->struct->unpack('<I', substr($packet, -4, null))[1])) {
throw new Exception('CRC32 was not correct!');
}
$x = $this->struct->unpack('<I', substr($packet, null, 4));
$auth_key_id = substr($packet, 4, 12 - 4);
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);
} else if ($auth_key_id == $this->auth_key_id) {
} elseif ($auth_key_id == $this->auth_key_id) {
$message_key = substr($packet, 12, 28 - 12);
$encrypted_data = substr($packet, 28, -4 - 28);
list($aes_key, $aes_iv) = $this->aes_calculate($message_key,'from server');
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, 'from server');
$decrypted_data = crypt::ige_decrypt($encrypted_data, $aes_key, $aes_iv);
assert((substr($decrypted_data, 0, 8 - 0) == $this->server_salt));
assert((substr($decrypted_data, 8, 16 - 8) == $this->session_id));
@ -204,27 +234,32 @@ class Session {
} else {
throw new Exception('Got unknown auth_key id');
}
return $data;
}
function method_call($method, $kwargs) {
public function method_call($method, $kwargs)
{
foreach (range(1, $this->MAX_RETRY) as $i) {
try {
//var_dump(py2php_kwargs_function_call('serialize_method', [$method], $kwargs));
$this->send_message($this->tl->serialize_method($method, $kwargs));
$server_answer = $this->recv_message();
}
catch(Exception $e) {
echo $e->getMessage() . PHP_EOL;
} catch (Exception $e) {
echo $e->getMessage().PHP_EOL;
pyjslib_printnl('Retry call method');
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);
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'];
$public_key_fingerprint = $ResPQ['server_public_key_fingerprints'][0];
$pq_bytes = $ResPQ['pq'];
@ -237,16 +272,16 @@ class Session {
pyjslib_printnl(sprintf('Factorization %d = %d * %d', [$pq, $p, $q]));
$p_bytes = long_to_bytes($p);
$q_bytes = long_to_bytes($q);
$f = pyjslib_open(__DIR__ . '/rsa.pub');
$f = pyjslib_open(__DIR__.'/rsa.pub');
$key = RSA::importKey($f->read());
$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);
$random_bytes = random_bytes(((255 - strlen($data)) - strlen($sha_digest)));
$to_encrypt = (($sha_digest + $data) + $random_bytes);
$encrypted_data = $key->encrypt($to_encrypt, 0) [0];
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(($server_nonce == $server_dh_params['server_nonce']));
$encrypted_answer = $server_dh_params['encrypted_answer'];
@ -272,19 +307,19 @@ class Session {
$b = new bytes_to_long($b_str);
$g_b = pow($g, $b, $dh_prime);
$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_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);
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_str = new long_to_bytes($auth_key);
$auth_key_sha = sha1($auth_key_str, true);
$auth_key_aux_hash = array_slice($auth_key_sha, null, 8);
$new_nonce_hash1 = array_slice(sha1($new_nonce . '' . $auth_key_aux_hash, true), -16, null);
$new_nonce_hash2 = array_slice(sha1($new_nonce . '' . $auth_key_aux_hash, true), -16, null);
$new_nonce_hash3 = array_slice(sha1($new_nonce . '' . $auth_key_aux_hash, true), -16, null);
$new_nonce_hash1 = array_slice(sha1($new_nonce.''.$auth_key_aux_hash, true), -16, null);
$new_nonce_hash2 = array_slice(sha1($new_nonce.''.$auth_key_aux_hash, true), -16, null);
$new_nonce_hash3 = array_slice(sha1($new_nonce.''.$auth_key_aux_hash, true), -16, null);
assert(($Set_client_DH_params_answer['nonce'] == $nonce));
assert(($Set_client_DH_params_answer['server_nonce'] == $server_nonce));
if (($Set_client_DH_params_answer->name == 'dh_gen_ok')) {
@ -294,11 +329,12 @@ class Session {
$this->auth_key = $auth_key_str;
$this->auth_key_id = array_slice($auth_key_sha, -8, null);
pyjslib_printnl('Auth key generated');
return 'Auth Ok';
} else if (($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));
pyjslib_printnl('Retry Auth');
} else if (($Set_client_DH_params_answer->name == 'dh_gen_fail')) {
} elseif (($Set_client_DH_params_answer->name == 'dh_gen_fail')) {
assert(($Set_client_DH_params_answer['new_nonce_hash3'] == $new_nonce_hash3));
pyjslib_printnl('Auth Failed');
throw new Exception('Auth Failed');
@ -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;
$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);
@ -315,6 +353,7 @@ class Session {
$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_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];
}
}

View File

@ -1,31 +1,39 @@
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
require_once ('libpy2php.php');
function everynth($array, $n) {
$result = array();
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once 'libpy2php.php';
function everynth($array, $n)
{
$result = [];
$i = -1;
foreach($array as $key => $value) {
foreach ($array as $key => $value) {
if ($i++ == $n) {
$i = 0;
}
if($i == 0) {
if ($i == 0) {
$result[$key] = $value;
}
}
return $result;
}
function array_merge_ignore_keys($array1, $array2) {
if(count($array1) == count($array2)) {
function array_merge_ignore_keys($array1, $array2)
{
if (count($array1) == count($array2)) {
$i = -1;
foreach ($array1 as $key => $val){
foreach ($array1 as $key => $val) {
$array1[$key] = $array2[$i++];
}
} else return null;
} else {
return;
}
return $array1;
}
function primesbelow($N) {
function primesbelow($N)
{
$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[0] = false;
foreach (pyjslib_range((floor(pyjslib_int(pow($N, 0.5)) / 3) + 1)) as $i) {
@ -37,10 +45,10 @@ function primesbelow($N) {
array_splice(
$sieve, floor(
(
$k*$k + 4*$k - 2*$k*($i%2)
$k * $k + 4 * $k - 2 * $k * ($i % 2)
) / 3
)
), 2*$k
), 2 * $k
),
(
array_fill(
@ -71,23 +79,29 @@ 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 = 100000;
function isprime($n, $precision = 7) {
function isprime($n, $precision = 7)
{
if (($n == 1) || (($n % 2) == 0)) {
return false;
} else if (($n < 1)) {
} elseif (($n < 1)) {
throw new $ValueError('Out of bounds, first argument must be > 0');
} else if (($n < $_smallprimeset)) {
} elseif (($n < $_smallprimeset)) {
return in_array($n, $smallprimeset);
}
$d = ($n - 1);
$s = 0;
while ((($d % 2) == 0)) {
$d = floor($d /2);
$s+= 1;
$d = floor($d / 2);
$s += 1;
}
foreach (pyjslib_range($precision) as $repeat) {
$a = random::randrange(2, ($n - 2));
@ -105,16 +119,18 @@ function isprime($n, $precision = 7) {
}
}
}
return true;
}
function pollard_brent($n) {
function pollard_brent($n)
{
if ((($n % 2) == 0)) {
return 2;
}
if ((($n % 3) == 0)) {
return 3;
}
list($y, $c, $m) = [random::randint(1, ($n - 1)), random::randint(1, ($n - 1)), random::randint(1, ($n - 1)) ];
list($y, $c, $m) = [random::randint(1, ($n - 1)), random::randint(1, ($n - 1)), random::randint(1, ($n - 1))];
list($g, $r, $q) = [1, 1, 1];
while (($g == 1)) {
$x = $y;
@ -129,9 +145,9 @@ function pollard_brent($n) {
$q = (($q * abs(($x - $y))) % $n);
}
$g = gcd($q, $n);
$k+= $m;
$k += $m;
}
$r*= 2;
$r *= 2;
}
if (($g == $n)) {
while (true) {
@ -142,10 +158,12 @@ function pollard_brent($n) {
}
}
}
return $g;
}
$smallprimes = primesbelow(10000);
function primefactors($n, $sort = false) {
function primefactors($n, $sort = false)
{
global $smallprimes;
$factors = [];
$limit = (pyjslib_int(pow($n, 0.5)) + 1);
@ -173,51 +191,56 @@ function primefactors($n, $sort = false) {
$factor = pollard_brent($n);
$factors->extend(primefactors($factor));
$n = floor($n / $factor);
}
if ($sort) {
$factors->sort();
}
return $factors;
}
function factorization($n) {
function factorization($n)
{
$factors = [];
foreach (primefactors($n) as $p1) {
try {
$factors[$p1]+= 1;
}
catch(KeyError $e) {
$factors[$p1] += 1;
} catch (KeyError $e) {
$factors[$p1] = 1;
}
}
return $factors;
}
$totients = [];
function totient($n) {
function totient($n)
{
if (($n == 0)) {
return 1;
}
try {
return $totients[$n];
}
catch(KeyError $e) {
} catch (KeyError $e) {
}
$tot = 1;
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;
return $tot;
}
function gcd($a, $b) {
function gcd($a, $b)
{
if (($a == $b)) {
return $a;
}
while (($b > 0)) {
list($a, $b) = [$b, ($a % $b) ];
list($a, $b) = [$b, ($a % $b)];
}
return $a;
}
function lcm($a, $b) {
function lcm($a, $b)
{
return floor(abs(($a * $b)) / gcd($a, $b));
}

View File

@ -1,27 +1,30 @@
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
require_once ('libpy2php.php');
require_once ('mtproto.php');
require_once ('classes/shell.php');
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
require_once 'libpy2php.php';
require_once 'mtproto.php';
require_once 'classes/shell.php';
if (!debug_backtrace()) {
$clidata = [];
$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']['flags'] = "h";
$clidata["help"] = $clidata["description"] . PHP_EOL . PHP_EOL . "Flags: ";
$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']['flags'] = 'h';
$clidata['help'] = $clidata['description'].PHP_EOL.PHP_EOL.'Flags: ';
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) {
$clidata["help"] .= $command . ", ";
$clidata['help'] .= $command.', ';
}
$clidata["help"] .= PHP_EOL;
if(isset(getopt($clidata['args']['flags'])["h"])) {
die($clidata["help"]);
$clidata['help'] .= PHP_EOL;
if (isset(getopt($clidata['args']['flags'])['h'])) {
die($clidata['help']);
}
if ($argc == 1) {
$newTelePyShell = new TelepyShell();

View File

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