If i have a listnode with the following defination
class ListNode {
public $val = 0;
public $next = null;
function __construct($val = 0, $next = null) {
$this->val = $val;
$this->next = $next;
}
}
How can i add an element to the end of the listnode and thus add int[i] elements by interation?
class ListNode {
public int $val = 0;
public ?ListNode $next = null;
function __construct(?int $val = 0, ?ListNode $next = null) {
$this->val = $val;
$this->next = $next;
}
function appendToListEnd(int $val) {
if ($this->next == null) {
$this->next = new ListNode($val);
} else {
$temp = $this->next;
while ($temp->next != null) {
$temp = $temp->next;
}
$temp->next = new ListNode($val);
}
}
}
$arr = [ 1, 2, 3, 4 ];
$listHead = new ListNode($arr[0]);
for ($i = 1; $i < count($arr); $i++) {
$listHead->appendToListEnd($arr[$i]);
}
print_r($listHead);
$listHead->appendToListEnd(5);
print_r($listHead);
I trying to make some simple library for encrypting files in PHP with OTP method. My problem is that some chars in decrypted code are different than original. I worked on it almost one week but without result. Is there problem with base64 chars or with encoding/decoding mechanism ?
Many thanks for the answers.
final class Otp
{
private static $charSet = array('+','/','0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L',
'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
's','t','u','v','w','x','y','z');
public static function encryptFile($originalFilePath, $encryptedFilePath, $keyFilePath)
{
if(!self::existsFile($keyFilePath) || !self::existsFile($encryptedFilePath)) {
if($originalFileData = self::existsFile($originalFilePath)) {
$originalFileBase64Data = base64_encode($originalFileData);
$originalFileBase64DataLength = strlen($originalFileBase64Data) - 1;
$originalFileBase64DataArray = str_split($originalFileBase64Data);
$encryptedData = NULL;
$encryptedDataKey = NULL;
for ($i = 0; $i <= $originalFileBase64DataLength; $i++) {
$randKey = rand(0, sizeOf(self::$charSet) - 1);
$arrayKey = array_search($originalFileBase64DataArray[$i], self::$charSet);
if($randKey > $arrayKey) {
$str = '-' . ($randKey - $arrayKey);
} elseif($randKey < $arrayKey) {
$str = ($randKey + $arrayKey);
} else {
$str = $randKey;
}
$encryptedData .= self::$charSet[$randKey];
$encryptedDataKey .= $str. ';';
}
$encryptedDataString = $encryptedData;
$encryptedDataKeyString = $encryptedDataKey;
if(!self::existsFile($keyFilePath)) {
file_put_contents($keyFilePath, $encryptedDataKeyString);
}
if(!self::existsFile($encryptedFilePath)) {
file_put_contents($encryptedFilePath, $encryptedDataString);
}
return 'OK';
} else {
return 'Source file not exists';
}
} else {
return 'Encrypted data already exists';
}
}
public static function decryptFile($encryptedFilePath, $keyFilePath, $decryptedFilePath)
{
$keyFileData = self::existsFile($keyFilePath);
$encryptedFileData = self::existsFile($encryptedFilePath);
$encryptedFileDataLength = strlen($encryptedFileData) - 1;
if($encryptedFileData && $keyFileData) {
$encryptedFileDataArray = str_split($encryptedFileData);
$keyFileDataArray = explode(';', $keyFileData);
$decryptedData = NULL;
for ($i = 0; $i <= $encryptedFileDataLength; $i++) {
$poziciaaktualneho = array_search($encryptedFileDataArray[$i], self::$charSet);
$poziciasifrovana = $keyFileDataArray[$i];
if($poziciasifrovana < 0) {
$move = $poziciasifrovana + $poziciaaktualneho;
} elseif($poziciasifrovana > 0) {
$move = $poziciasifrovana - $poziciaaktualneho;
} else {
$move = '0';
}
$decryptedData .= self::$charSet[$move];
}
if(!self::existsFile($decryptedFilePath)) {
file_put_contents($decryptedFilePath, base64_decode($decryptedData));
return 'OK';
} else {
return 'Decrypted data already exists';
}
}
}
private static function existsFile($filePath)
{
$fileData = #file_get_contents($filePath);
if($fileData) {
return $fileData;
}
return FALSE;
}
}
$originalFilePath = 'original.jpg';
$keyFilePath = 'Otp_Key_' . $originalFilePath;
$encryptedFilePath = 'Otp_Data_' . $originalFilePath;
$decryptedFilePath = 'Otp_Decrypted_' . $originalFilePath;
echo Otp::encryptFile($originalFilePath, $encryptedFilePath, $keyFilePath);
echo Otp::decryptFile($encryptedFilePath, $keyFilePath, $decryptedFilePath);
The problem seems to be only happening when $poziciaaktualneho is equal to $poziciasifrovana and so by adding another if statement on line 78 to check for this and instead set $move equal to $poziciasifrovana I was able to fix the problem. The below script should work:
final class Otp
{
private static $charSet = array('+','/','0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L',
'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
's','t','u','v','w','x','y','z');
public static function encryptFile($originalFilePath, $encryptedFilePath, $keyFilePath)
{
if(!self::existsFile($keyFilePath) || !self::existsFile($encryptedFilePath)) {
if($originalFileData = self::existsFile($originalFilePath)) {
$originalFileBase64Data = base64_encode($originalFileData);
$originalFileBase64DataLength = strlen($originalFileBase64Data) - 1;
$originalFileBase64DataArray = str_split($originalFileBase64Data);
$encryptedData = NULL;
$encryptedDataKey = NULL;
for ($i = 0; $i <= $originalFileBase64DataLength; $i++) {
$randKey = rand(0, sizeOf(self::$charSet) - 1);
$arrayKey = array_search($originalFileBase64DataArray[$i], self::$charSet);
if($randKey > $arrayKey) {
$str = '-' . ($randKey - $arrayKey);
} elseif($randKey < $arrayKey) {
$str = ($randKey + $arrayKey);
} else {
$str = $randKey;
}
$encryptedData .= self::$charSet[$randKey];
$encryptedDataKey .= $str. ';';
}
$encryptedDataString = $encryptedData;
$encryptedDataKeyString = $encryptedDataKey;
if(!self::existsFile($keyFilePath)) {
file_put_contents($keyFilePath, $encryptedDataKeyString);
}
if(!self::existsFile($encryptedFilePath)) {
file_put_contents($encryptedFilePath, $encryptedDataString);
}
return 'OK';
} else {
return 'Source file not exists';
}
} else {
return 'Encrypted data already exists';
}
}
public static function decryptFile($encryptedFilePath, $keyFilePath, $decryptedFilePath)
{
$keyFileData = self::existsFile($keyFilePath);
$encryptedFileData = self::existsFile($encryptedFilePath);
$encryptedFileDataLength = strlen($encryptedFileData) - 1;
if($encryptedFileData && $keyFileData) {
$encryptedFileDataArray = str_split($encryptedFileData);
$keyFileDataArray = explode(';', $keyFileData);
$decryptedData = NULL;
for ($i = 0; $i <= $encryptedFileDataLength; $i++) {
$poziciaaktualneho = array_search($encryptedFileDataArray[$i], self::$charSet);
$poziciasifrovana = $keyFileDataArray[$i];
if ($poziciasifrovana == $poziciaaktualneho) {
$move = $poziciasifrovana;
} elseif($poziciasifrovana < 0) {
$move = $poziciasifrovana + $poziciaaktualneho;
} elseif($poziciasifrovana > 0) {
$move = $poziciasifrovana - $poziciaaktualneho;
} else {
$move = '0';
}
$decryptedData .= self::$charSet[$move];
}
if(!self::existsFile($decryptedFilePath)) {
file_put_contents($decryptedFilePath, base64_decode($decryptedData));
return 'OK';
} else {
return 'Decrypted data already exists';
}
}
}
private static function existsFile($filePath)
{
$fileData = #file_get_contents($filePath);
if($fileData) {
return $fileData;
}
return FALSE;
}
}
$originalFilePath = 'original.jpg';
$keyFilePath = 'Otp_Key_' . $originalFilePath;
$encryptedFilePath = 'Otp_Data_' . $originalFilePath;
$decryptedFilePath = 'Otp_Decrypted_' . $originalFilePath;
echo Otp::encryptFile($originalFilePath, $encryptedFilePath, $keyFilePath);
echo Otp::decryptFile($encryptedFilePath, $keyFilePath, $decryptedFilePath);
Warning: I would not recommend using my solution in an enterprise setting if at all since I do not know why this fixes your script or what was
originally wrong with it and it is most likely not air tight.
I got this class code from https://github.com/ricardotiago/sec-gov-api, which is used to retrieve and parse quarterly and yearly reports from the U.S Securities Exchange website.I do not understand how to print the results and what sort of parameters it's accepts. Is$sSmbol an input parameter, how do I pass this parameter so that it displays the quarterly and yearly report
<?php
require_once "parallelCurl.php";
class SecGovAPI {
const SEARCH_LINK = "http://www.sec.gov/cgi-bin/browse-edgar";
const BASE_LINK = "http://www.sec.gov/";
const QUARTERLY_REPORT = '10-Q';
const YEARLY_REPORT = '10-K';
const MOST_RECENT_REPORT = 0;
const ALL_REPORTS = 1;
public function __construct($sSymbol) {
$this->oParallelCurl = new ParallelCurl();
$this->sSymbol = $sSymbol;
$this->oDoc = new DOMDocument();
$this->report = array();
}
public function getQuaterlyReport($iSearchType = SecGovAPI::MOST_RECENT_REPORT) {
if ($iSearchType !== SecGovAPI::MOST_RECENT_REPORT && $iSearchType !== SecGovAPI::ALL_REPORTS) {
return array();
}
$aReportLinks = $this->search(SecGovAPI::QUARTERLY_REPORT, $iSearchType);
var_dump($aReportLinks);
foreach ($aReportLinks as $link) {
$this->oParallelCurl->addUrl(SecGovAPI::BASE_LINK."/".$link);
}
$aData = $this->oParallelCurl->run();
foreach ($aData as $link => $xml) {
$this->oDoc->loadXML($xml);
$oXPath = new DOMXPath($this->oDoc);
$oXPath->registerNamespace("xbrli", "http://www.xbrl.org/2003/instance");
$this->getReportData($oXPath, $link, "dei:EntityCommonStockSharesOutstanding", "CommonStockSharesOutstanding");
$this->getReportData($oXPath, $link, "us-gaap:NetIncomeLoss", "NetIncomeLoss");
}
var_dump($this->report);
}
public function getYearlyReport($iSearchType = SecGovAPI::MOST_RECENT_REPORT) {
if ($iSearchType !== SecGovAPI::MOST_RECENT_REPORT && $iSearchType !== SecGovAPI::ALL_REPORTS) {
return array();
}
$aReportLinks = $this->search(SecGovAPI::YEARLY_REPORT, $iSearchType);
var_dump($aReportLinks);
foreach ($aReportLinks as $link) {
$this->oParallelCurl->addUrl(SecGovAPI::BASE_LINK."/".$link);
}
$aData = $this->oParallelCurl->run();
foreach ($aData as $link => $xml) {
$this->oDoc->loadXML($xml);
$oXPath = new DOMXPath($this->oDoc);
$oXPath->registerNamespace("xbrli", "http://www.xbrl.org/2003/instance");
$this->getReportData($oXPath, $link, "dei:EntityCommonStockSharesOutstanding", "CommonStockSharesOutstanding");
$this->getReportData($oXPath, $link, "us-gaap:NetIncomeLoss", "NetIncomeLoss");
}
var_dump($this->report);
}
public function getReportData($oXPath, $link, $sEntity, $sSaveAs) {
$oNodelist = $oXPath->query("//xbrli:xbrl/".$sEntity);
for ($i = 0; $i < $oNodelist->length; $i++) {
$this->report[$link][$sSaveAs][$i] = $oNodelist->item($i)->nodeValue;
}
}
protected function search($sType, $iSearchType) {
$aParams = array("company" => "",
"match" => "",
"CIK" => $this->sSymbol,
"filenum" => "",
"State" => "",
"Country" => "",
"SIC" => "",
"count" => "40",
"owner" => "exclude",
"Find" => "Find Companies",
"action" => "getcompany",
"type" => $sType,
"output" => "atom");
$sUrl = SecGovAPI::SEARCH_LINK . "?". http_build_query($aParams);
$this->oDoc->load($sUrl);
$oXPath = new DOMXPath($this->oDoc);
$oXPath->registerNamespace("atom", "http://www.w3.org/2005/Atom");
$aLinks = $this->getReportLinks($oXPath, $iSearchType);
$aReportLinks = array();
foreach ($aLinks as $link) {
$this->oParallelCurl->addUrl($link);
}
$aHtmls = $this->oParallelCurl->run();
foreach ($aHtmls as $html) {
$this->oDoc->loadHTML($html);
$oXPath = new DOMXPath($this->oDoc);
$oNodeList = $oXPath->query('//table[#summary="Data Files"]/tr[2]/td[3]/a');
if ($oNodeList->length === 0) continue;
$aReportLinks[] = $oNodeList->item(0)->getAttribute("href");
}
return $aReportLinks;
}
protected function getReportLinks($oXPath, $iSearchType) {
if ($iSearchType === SecGovAPI::MOST_RECENT_REPORT) {
$aNodeList = $oXPath->query("//atom:feed/atom:entry[1]/atom:link");
if ($aNodeList->length === 1)
return array($aNodeList->item(0)->getAttribute("href"));
else
return null;
}
else if ($iSearchType === SecGovAPI::ALL_REPORTS) {
$aNodeList = $oXPath->query("//atom:feed/atom:entry/atom:link");
for ($i = 0; $i < $aNodeList->length; $i++) {
$aReportLinks[] = $aNodeList->item($i)->getAttribute("href");
}
return $aReportLinks;
}
else return null;
}
protected function getAccessionNumber($oXPath, $iSearchType) {
if ($iSearchType === SecGovAPI::MOST_RECENT_REPORT) {
$aNodeList = $oXPath->query("//atom:feed/atom:entry[1]/atom:id");
if ($aNodeList->length === 1) $sRawAccessNumber = $aNodeList->item(0)->nodeValue;
else return null;
return $this->processAccessionNumber($sRawAccessNumber);
}
else if ($iSearchType === SecGovAPI::ALL_REPORTS) {
$aNodeList = $oXPath->query("//atom:feed/atom:entry/atom:id");
for ($i = 0; $i < $aNodeList->length; $i++) {
$sRawAccessNumber = $aNodeList->item($i)->nodeValue;
$aAccessionNumber[] = $this->processAccessionNumber($sRawAccessNumber);
}
return $aAccessionNumber;
}
else return null;
}
protected function processAccessionNumber($sRawAccessNumber) {
$aSplitData = preg_split('/accession-number=/', $sRawAccessNumber);
if (!isset($aSplitData[1])) return null;
$sAccessionNumber = str_replace('-','', $aSplitData[1]);
return $sAccessionNumber;
}
protected function getReportDate($oXPath, $iSearchType) {
if ($iSearchType === SecGovAPI::MOST_RECENT_REPORT) {
$aNodeList = $oXPath->query("//atom:feed/atom:entry[1]/atom:updated");
if ($aNodeList->length === 1)
return $sUpdated = $aNodeList->item(0)->nodeValue;
else
return null;
}
else if ($iSearchType === SecGovAPI::ALL_REPORTS) {
$aNodeList = $oXPath->query("//atom:feed/atom:entry/atom:updated");
for ($i = 0; $i < $aNodeList->length; $i++) {
$aUpdated[] = $aNodeList->item($i)->nodeValue;
}
return $aUpdated;
}
else return null;
}
}
?>
parallelCurl.php
<?php
class ParallelCurl {
protected $aHandlers;
public function __construct() {
$this->aHandlers = array();
$this->rMultiHandler = curl_multi_init();
}
public function addUrl($sUrl) {
$rHandler = curl_init();
curl_setopt($rHandler, CURLOPT_URL, $sUrl);
curl_setopt($rHandler, CURLOPT_HEADER, 0);
curl_setopt($rHandler, CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($this->rMultiHandler, $rHandler);
$this->aHandlers[$sUrl] = $rHandler;
}
public function run() {
$blsRunning = null;
do {
$rHandler = curl_multi_exec($this->rMultiHandler, $blsRunning);
} while ($rHandler === CURLM_CALL_MULTI_PERFORM);
while ($blsRunning && $rHandler == CURLM_OK) {
if (curl_multi_select($this->rMultiHandler) != -1) {
do {
$rHandler = curl_multi_exec($this->rMultiHandler, $blsRunning);
} while ($rHandler == CURLM_CALL_MULTI_PERFORM);
}
}
foreach ($this->aHandlers as $url => $handler) {
$data[$url] = curl_multi_getcontent($handler);
curl_multi_remove_handle($this->rMultiHandler, $handler);
}
$this->aHandlers = array();
return $data;
}
public function __destruct() {
curl_multi_close($this->rMultiHandler);
}
}
?>
To create an instance of the SecGovAPI class you can use the new keyword:
$class = new SecGovAPI($sSymbol);
then you can call the methods getQuaterlyReport and getYearlyReport with:
echo $class->getQuaterlyReport();
echo $class->getYearlyReport();
Both these methods has an argument, and by default is SecGovAPI::MOST_RECENT_REPORT. You can also use:
SecGovAPI::QUARTERLY_REPORT
SecGovAPI::YEARLY_REPORT
SecGovAPI::ALL_REPORTS
Example:
echo $class->getQuaterlyReport(SecGovAPI::QUARTERLY_REPORT);
I am getting undefined variable for periods and subPeriods on the last line of this program. not sure what the problem is. Could it be my instances?
This is my first proper attempt at oop in PHP so i am sure i am doing something wrong.
$global_periods = 5;
$global_subperiods = 2;
$questionslist = array("q_1_1", "q_1_2", "q_2_1", "q_2_2", "q_3_1", "q_4_1", "q_5_1");
class User {
public $userId;
public $periods = array();
public function __construct($number)
{
$this->userId = $number;
}
public function addPeriod($pno)
{
$periods[] = new Period($pno);
}
}
class Period {
public $periodNo;
public $subPeriods = array();
public function __construct($number)
{
$this->periodNo = $number;
}
public function addSubPeriod($spno)
{
$subPeriods[] = new SubPeriod($spno);
}
}
class SubPeriod {
public $SubPeriodNo;
public $answers = array();
public function __construct($number)
{
$this->SubPeriodNo = $number;
}
public function addAnswer($answer)
{
$answers[] = new Answer($answer);
}
}
class Question {
public $answer;
public function __construct($ans)
{
$this->answer = $ans;
}
public function getAnswer()
{
echo $answer;
}
}
$userlist = array();
$sql = 'SELECT user_ref FROM _survey_1_as GROUP BY user_ref ORDER BY user_ref ASC';
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result))
{
$userlist[] = new User($row['user_ref']);
}
for ($i = 0; $i >= count($userlist); $i++)
{
for ($x = 1; $x > $global_periods; $x++)
{
$userlist[i]->addPeriod($x);
for ($y = 1; $y > $global_subperiods; $y++)
{
$userlist[i]->$periods[x]->addSubPeriod($y);
foreach($questionslist as $aquestion)
{
$sql = 'SELECT ' . $questionNumber . ' FROM _survey_1_as WHERE user_ref = ' .
$i . ' AND answer_sub_period = ' . $y . ' AND answer_period = ' . $x .'';
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result))
{
$userlist[i]->$periods[x]->$subPeriods[y]->addAnswer($row[$questionNumber]);
}
}
}
}
}
$userlist[3]->$periods[2]->$subPeriods[2]->getAnswer();
Remove all the $ signs behind the $userlist, you only need to define the first variable. You can't use dollar signs like this, this way, it will try get the value of the word after the $ sign and call that, but that variable doesn't exist.
I have a folder that contains subfolders of years (e.g. 2011, 2012 etc.). Each year's folder contains month folders (e.g 02, 09 etc).
How do I calculate the total size of the month folders and list them along with the year and month folder names?
Example:
Directory Name - Size
06/2008 - 52KB
10/2010 - 151MB
27/2012 - 852MB
12/01/2013 - 5GB
Cheers.
You can try
echo "<pre>";
$depth = 1;
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST);
$r = array();
foreach ( $ritit as $splFileInfo ) {
if ($ritit->getDepth() === $depth && $splFileInfo->isDir()) {
printf("%s - %s \n", $splFileInfo, getSize($splFileInfo));
}
}
function getSize($dir, $precision = 2) {
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS));
$bytes = 0;
foreach ( $ritit as $v ) {
$bytes += $v->getSize();
}
$units = array('B','KB','MB','GB','TB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
You can also try this approach using FilterIterator
$depth = 1;
$it = new RecursiveDirectoryIterator("./", RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST);
$it = new FileDepthFilterIterator($it, $depth, FileDepthFilterIterator::ONLY_DIR);
foreach ( $it as $splFileInfo ) {
printf("%s\n", new RecusiveSizeInfo($splFileInfo));
}
Classes used
class FileDepthFilterIterator extends FilterIterator {
private $it;
private $depth;
private $type;
const ONLY_DIR = 1;
const ONLY_FILE = 2;
const BOTH_DIR_FILE = 3;
function __construct(RecursiveIteratorIterator &$iterator, $depth, $type) {
$this->it = &$iterator;
$this->depth = $depth;
$this->type = $type;
parent::__construct($this->it);
}
function accept() {
if ($this->getDepth() != $this->depth) {
return false;
}
if ($this->type == self::ONLY_DIR && ! $this->getInnerIterator()->current()->isDir()) {
return false;
}
if ($this->type == self::ONLY_FILE && ! $this->getInnerIterator()->current()->isFile()) {
return false;
}
return true;
}
}
class RecusiveSizeInfo {
/**
*
* #var SplFileInfo
*/
private $info;
private $numFiles = 0;
private $numFolder = 0;
private $bytes = 0;
function __construct(SplFileInfo $info) {
$this->info = $info;
$this->parse();
}
public function getNumFiles() {
return $this->numFiles;
}
public function getNumFolder() {
return $this->numFolder;
}
public function getBytes() {
return $this->bytes;
}
public function __toString() {
return sprintf("%s\t%s\t%s", $this->info, $this->formatSize($this->getBytes()), json_encode(array("file" => $this->numFiles,"dir" => $this->numFolder)));
}
private function parse() {
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->info , RecursiveDirectoryIterator::SKIP_DOTS),RecursiveIteratorIterator::SELF_FIRST);
foreach ( $ritit as $v ) {
$v->isFile() and $this->numFiles ++;
$v->isDir() and $this->numFolder ++;
$this->bytes += $v->getSize();
}
}
private function formatSize($bytes) {
$units = array('B','KB','MB','GB','TB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, 2) . ' ' . $units[$pow];
}
}
Look at this answer to work out the size of directories. To implement, you're going to need to traverse your directory structure recursively, or manually specify the directories you want:
<li>2012/01 <?php echo foldersize('/2012/01'); ?></li>
<li>2012/02 <?php echo foldersize('/2012/01'); ?></li>