I'm trying to create a simple hash to use as a key value pare in PHP. According to the PHP best practices I should use password_hash and then password_verify to confirm they match.
However, I found that there were multiple values (in the example there are 56 matches).
<?php
echo '<pre>';
$apiKey = hash('sha512', uniqid());
$apiToken = hash('sha512', uniqid());
$apiTokenHash = password_hash($apiToken, PASSWORD_DEFAULT);
echo '$apiKey = ' . $apiKey . ' length = ' . strlen($apiKey) . '<br/>';
echo '$apiToken = ' . $apiToken . ' length = ' . strlen($apiToken) . '<br/>';
echo '$apiTokenHash = ' . $apiTokenHash . ' length = ' . strlen($apiTokenHash) . '<br/>';
$verify = password_verify($apiToken, $apiTokenHash);
$style = ($verify) ? "color: green;" : '';
echo "<p style='{$style}'>({$apiToken} === {$apiTokenHash})</p>";
$count = 1;
while(strlen($apiToken) > 0) {
$apiToken = substr($apiToken, 0, -1);
$verify = password_verify($apiToken, $apiTokenHash);
$style = ($verify) ? "color: green;" : '';
echo "<p style='{$style}'>{$count} - ({$apiToken} === {$apiTokenHash})</p>";
$count++;
}
?>
Does anyone understand why password_verify is accepting so many answers.
P.S. I really really tried to get this in a PHP fiddle for you but I cant figure out how to share a link to it so please dont give me a hard time about that.
The bcrypt algorithm used by password_hash() cannot hash strings longer than 72 characters. Longer strings are truncated before being hashed.
Related
I am a beginner programmer. Only in php.
On php, am at procedural style. Not on oop or pdo yet. Hence, you see mysqli and procedural style.
I am building a SERP with pagination. Like google, when they show you your keywords search result.
Don't mistake my thread. Not trying to prevent Sql injection as I managed to do it using prepared statements.
Learning to use urlencode(), rawurlencode(), htmlentities() as I'm trying to use them to prevent user's injecting unwanted html tags to breakup the html of my SERPs.
On this occasion, I am having problem using urlencode() properly.
I get this error:
Warning: urlencode() expects parameter 1 to be string, array given in ... on line ...
Following are the concerned lines as I urlencode() their values so no user (keywords searcher) can inject html tags to breakup the html of my SERP:
$search = $_GET['search']; //Keyword(s) to search.
$col = $_GET['col']; //MySql Tbl Col to search.
$tbl = $_GET['tbl']; //MySql Tbl to search.
$max = $_GET['max']; //Max Result per page.
$page = $_GET['page']; //Serp Number.
The above vars contain one values each as each $_GET contains one value each, even though $_GET is a a global variable (array). So here, nothing to do with arrays or more than one value per each variable.
Issue is on this following line that comes just after the WHILE loop:
LINE 145
$query_string_1 = '?search=' .urlencode($search) .'&tbl=' .urlencode($tbl) .'&col=' .urlencode($col) .'&max=' .intval($max);
Here is the code context:
//ERROR REPORTING FOR DEVMODE ONLY.
ini_set('display_errors','1');
ini_set('display_startup_errors','1');
error_reporting(E_ALL);
//MYSQLI CONNECTION.
mysqli_report(MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT);
$server = 'localhost';
$user = 'root';
$password = '';
$database = 'brute';
if(!$conn = mysqli_connect("$server","$user","$password","$database"))
{
echo 'Mysqli Connection Error' .mysqli_connect_error($conn);
echo 'Mysqli Connection Error Number' .mysqli_connect_errno($conn);
}
if(!mysqli_character_set_name($conn) == 'utf8mb4')
{
echo 'Initial Character Set: ' .mysqli_character_set_name($conn);
mysqli_set_charset("$conn",'utf8mb4');
echo 'Current Character Set: ' .mysqli_character_set_name($conn);
}
//PAGINATION SECTION.
$search = $_GET['search']; //Keyword(s) to search.
$col = $_GET['col']; //MySql Tbl Col to search.
$tbl = $_GET['tbl']; //MySql Tbl to search.
$max = $_GET['max']; //Max Result per page.
$page = $_GET['page']; //Serp Number.
//QUERY DATABASE FOR KEYWORD COUNT.
$query = "SELECT COUNT(id) From links WHERE keyword = ?";
$stmt = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt,$query))
{
mysqli_stmt_bind_param($stmt,'s',$search);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt,$row_count);
if(mysqli_stmt_fetch($stmt))
{
echo 'Row Count: ' .$row_count; echo '<br>';
}
else
{
echo 'Record fetching failed!';
echo 'Error: ' .mysqli_stmt_error($conn);
echo 'Error: ' .mysqli_stmt_errno($conn);
}
mysqli_stmt_close($stmt);
}
else
{
echo 'Search Preparation Failed!';
}
//mysqli_close($conn);
echo '<b>'; echo __LINE__; echo '</b>'; echo '<br>';
//START KEYWORD SEARCH & OUTPUT RESULT
echo $offset = ($page*$max)-$max; echo '<br>';
echo '<b>'; echo __LINE__; echo '</b>'; echo '<br>';
$query = "SELECT id,date_and_time,domain,domain_email,ip,url,anchor,title,description,keyword,keyphrase From links WHERE keyword = ? LIMIT $offset,$max";
$stmt = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt,$query))
{
mysqli_stmt_bind_param($stmt,'s',$search);
mysqli_stmt_execute($stmt);
if($result = mysqli_stmt_get_result($stmt))
{
/*
FOLLOWING BOTH ARE EQUAL:
$col = mysqli_fetch_array($result) //SHORT VERSION.
$col = mysqli_fetch_array($result,MYSQLI_BOTH) //LONG VERSION.
*/
$col = mysqli_fetch_array($result); //SHORT VERSION.
$id = $col['0']; //MYSQLI_NUM
$date_and_time = $col['date_and_time']; //MYSQLI_ASSOC
$domain = $col['2']; //MYSQLI_NUM
$domain_email = $col['domain_email']; //MYSQLI_ASSOC
$ip = $col['4']; //MYSQLI_NUM
$url = $col['url']; //MYSQLI_ASSOC
$anchor = $col['6']; //MYSQLI_NUM
$title = $col['title']; //MYSQLI_ASSOC
$description = $col['8']; //MYSQLI_NUM
$keyword = $col['keyword']; //MYSQLI_ASSOC
$keyphrase = $col['10']; //MYSQLI_NUM
echo 'Id: ' .$id; echo '<br>';
echo 'Date And Time: ' .$date_and_time; echo '<br>';
echo 'Domain: ' .$domain; echo '<br>';
echo 'Domain Email: ' .$domain_email; echo '<br>';
echo 'Ip: ' .$ip; echo '<br>';
echo 'Url: ' .$url; echo '<br>';
echo 'Anchor: ' .$anchor; echo '<br>';
echo 'Title: ' .$title; echo '<br>';
echo 'Description: ' .$description; echo '<br>';
echo 'Keyword: ' .$keyword; echo '<br>';
echo 'Keyphrase: ' .$keyphrase; echo '<br>';
}
else
{
echo 'Record fetching failed!';
echo 'Error: ' .mysqli_stmt_error($stmt);
echo 'Error: ' .mysqli_stmt_errno($stmt);
}
mysqli_stmt_close($stmt);
}
mysqli_close($conn);
echo '<b>'; echo __LINE__; echo '</b>'; echo '<br>';
//PAGINATION SECTION TO NUMBER THE PAGES AND LINK THEM.
$total_pages = ceil($row_count/$max);
$i = '1';
//$selfpage = $_SERVER['PHP_SELF'];
$selfpage = basename(__FILE__,''); //Echoes: url_encode_Template.php. Does not fetch the url $_GET params.
$path = rawurlencode($selfpage);
$query_string_1 = '?search=' .urlencode($search) .'&tbl=' .urlencode($tbl) .'&col=' .urlencode($col) .'&max=' .intval($max);
while($i<=$total_pages)
{
$query_string_2 = '&page=' .intval($i);
$url = $path .htmlentities($query_string_1) .htmlentities($query_string_2); //Full URL With $_GET params: https://localhost/Templates/url_encode_Template.php?search=keyword&tbl=links&col=keyword&max=100&page=1
if($page == $i)
{
echo '<a href=' .'"' .$url .'"' .'>' .'<b>' .intval($i) .'</b>' .'</a>';
}
else
{
echo '<a href=' .'"' .$url .'"' .'>' .intval($i) .'</a>';
}
$i++;
}
?>
Frankly, the pagination page is nearly finished, had it not been for this urlencode() issue!
If you spot any other errors which I have not asked about it's subject due to overlooking them then kindly show me a code sample by editing my code in order to show me how I really should've coded it. (I'm talking about my usage of urlencode(), rawurlencode(), htmlentities() as I'm trying to use them to prevent user's injecting unwanted html tags) to breakup my SERP.
I'd appreciate it if my code is edited by someone and the correction is displayed on this thread, wherever I went wrong.
Your problem is that you are overwriting the value of the $col variable that you initially populate with the 'col' parameter in the GET request with the result of your keyword search.
$col = $_GET['col']; //MySql Tbl Col to search.
...
$col = mysqli_fetch_array($result); //SHORT VERSION.
You do not seem to be using the col parameter for anything, you may be able to just remove it from the query string. If you do intend to use it, simply rename the variable you are using for the query result row.
For future reference, you can encode array values into a query string using the http_build_query function. This would simplify your code, and would have allowed you to see were the problem is in this case.
// Set some test values for the parameters
$search = 'my search term';
$tbl = 'my_table_name';
$col = 'column_1';
$max = 10;
// Simulate variable being overwritten with database result
$col = [
'id' => 123,
'date_and_time' => '2021-06-20 09:44:00',
'domain' => 'stackoverflow.com'
];
// Build an array of the parameters to be included in the query string
$queryParameters = [
'search' => $search,
'tbl' => $tbl,
'col' => $col,
'max' => $max
];
/*
* Build the query string using http_build_query
* Any array values will be represented appropriately
* Prepend the ? to the result
*/
$query_string_1 = '?'.http_build_query($queryParameters);
echo $query_string_1.PHP_EOL;
I'm pretty new to webcoding and would like to improve a bit in php, but I'm already stuck :/
What I am trying to do is to have a sentence like
"Simon likes apples"
Now I have an input form for the name so I can choose the name. So it looks like
"$name likes apples"
<table>
<tr>
<td><input type="text" id="name1" name="name1"></td>
<td><input type="submit" id="submit" name="submit" value="Apply"></td>
</tr>
</table>
</div>
<div id="text">
<?php
if(isset($_REQUEST['submit'])) {
$name1 = $_REQUEST['name1'];
echo "$name1 likes apples.";
}
?>
</div>
</form>
Everything fine till now. Whatever name I type in replaces $name. Now what I want to do is to change the "likes" to "like" whenever i type in a pronoun (I, You, They etc.), which makes sense obviously. Now here is where I don't know what to do. My current code (which doesnt work) looks like this:
<?php
if(isset($_REQUEST['submit'])) {
$name1 = $_REQUEST['name1'];
if ($name1 = "I", "You") {
$verb = "like";
}
else {
$verb = "likes";
}
echo "$name1 $verb apples";
}
?>
Also is there a way to make it case insensitive?
there are few problems in your code .
single = means SET my variable to whatever string is after . so if you want to see if your variable is equal to a string like You , you have to use == , it will return true or false .
now we want to say if my variable was You or I , change my second variable to like . thats gonna be the output :
if ($name1 == "I" || $name1 == "You") {
$verb = "like";
}
else {
$verb = "likes";
}
so now it says if $name1 was equal to I OR(||) $name1 was equal to You , change the $verb to like .
we use || as OR and && as AND.
if you want echo variables and string you should use . as split between your variable and string . so it will be like this :
echo $name1 . $verb . "apples";
it's kind of like + but not in a math way , it just means add .
UPDATE
yes . there is a way to check your string case insensitive . you have to use strcasecmp() .
in your code , it should be like :
if (strcasecmp($name1,"I") == 0 || strcasecmp($name1,"You") == 0 ) {
$verb = "like";
}
else {
$verb = "likes";
}
Case insensitive replacement, $lut table defines what should be replaced with what. You may place it inside the replaceMe function if you don't want to change it over time.
Code:
<?php
$lut = [
'like' => [
'I',
'You',
'They',
'We',
],
'likes' => [
'she',
'he',
'it',
'someone',
'somebody',
],
];
function replaceMe(string $name, array $lut) : string
{
foreach ($lut as $key => $value) {
$nameLower = strtolower($name);
$valueLowerArr = array_map(
function($input) {
return strtolower($input);
},
$value
);
if (in_array($nameLower, $valueLowerArr)) {
return strtolower($key);
}
}
return '';
}
$name = 'She';
echo "$name = " . replaceMe($name, $lut) . '<br>' . PHP_EOL;
$name = 'I';
echo "$name = " . replaceMe($name, $lut) . '<br>' . PHP_EOL;
$name = 'iT';
echo "$name = " . replaceMe($name, $lut) . '<br>' . PHP_EOL;
$name = 'TheY';
echo "$name = " . replaceMe($name, $lut) . '<br>' . PHP_EOL;
$name = 'nobody';
echo "$name = " . replaceMe($name, $lut) . '<br>' . PHP_EOL;
Gives Result:
She = likes<br>
I = like<br>
iT = likes<br>
TheY = like<br>
nobody = <br>
i'm relatively new to laravel and i'm having issues when trying to convert this function to laravel's query builder. This is the function i've been given which also runs a python script to decrypt the database.
Using the documentation from laravel.com you can do something like this:
function call($unitId)
{
$pfContact = DB::table('PFContact')
->where('UnitID', $unitId)
->latest() // Order by created_at
->first([ // Only retrieve these columns
'Send',
'Receive',
'Core',
'lock'
]);
$pfReadings = DB::table('PFReadings')
->get();
$rowCount = $pfReadings->count();
foreach ($pfReadings as $i => $reading) {
echo $i < count($reading) / $rowCount;
foreach ($reading as $column => $value) {
echo shell_exec(
'python3 enc.py ' . $value
. ' ' . $pfContact->Send
. ' ' . $pfContact->Receive
. ' ' . $pfContact->Core
. ' ' . $pfContact->lock . ' '
. $unitId . ' l'
) . '~';
}
echo ';';
}
}
And although I do not know what arguments this pyhton script needs you should really think this through. Why would you use PHP for this and not just handle everything from the python (or php) side because this looks over complicated to me.
How can I cache (using ModX's cacheManager), the dynamic placeholders i am generating here:
// recursive function to generate our un-ordered list of menu items
if(!function_exists('GenerateMenu')){
function GenerateMenu($level, $parent = 0, $wc, $wi, $we, $cs, $sc, $cl){
try {
$lvl = ++$level;
global $modx;
// Check for #1, should this be cached, #2 does it already exist in the cache
$cached = $modx->cacheManager->get('Navigator');
if($sc && isset($cached)){
// need to get the placeholders from cache - here somehow!
return $cached;
}else{
// get the site start
$siteStartId = $modx->getOption('site_start');
// Set our initial rows array
$rows = array();
// Run our query to get our menu items
$sql = 'Select `id`, `menutitle`, `uri`, `longtitle`, `parent`, `link_attributes`, `class_key`, `content`, `alias`, `introtext`
From `' . $modx->getOption(xPDO::OPT_TABLE_PREFIX) . 'site_content`
Where `deleted` = 0 AND `hidemenu` = 0 AND `published` = 1 AND `parent` = :parent
Order by `parent`, `menuindex`';
$query = new xPDOCriteria($modx, $sql, array(':parent' => $parent));
if ($query->stmt && $query->stmt->execute()) {
$rows = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
}
// do some cleanup
unset($query, $sql);
// make sure we have some rows, and then build our html for the menu
if($rows){
// grab a count of our results
$rCt = count($rows);
$cls = ($lvl > 1) ? 'sub-item-' . $lvl : 'main-item-' . $lvl;
$ret .= ' <ul class="' . $cls . '" id="' . $cls . '-' . $parent . '">' . "\r\n";
for($i = 0; $i < $rCt; ++$i){
// if this resource is a WebLink, show the content in it, as the URL for the href tag, otherwise, use the resource's URI
$url = ($rows[$i]['class_key'] == 'modWebLink') ? $rows[$i]['content'] : '/' . $rows[$i]['uri'];
// Check for the site's start id, if true, show a "blank" link, otherwise show the $url
$showUrl = ($siteStartId == $rows[$i]['id']) ? '/' : $url;
$la = (strlen($rows[$i]['link_attributes']) > 0) ? ' ' . $rows[$i]['link_attributes'] : null;
// Set some dynamic placeholders, they can only be used ont he pages that contain this snippet
$modx->toPlaceholders(array('Title-' . $rows[$i]['id'] => $rows[$i]['longtitle'],
'MenuTitle-' . $rows[$i]['id'] => $rows[$i]['menutitle'],
'URL-' . $rows[$i]['id'] => $showUrl),
'link');
$ret .= ' <li class="' . $cls . '" id="' . $rows[$i]['alias'] . '">' . "\r\n";
$ret .= ' <a href="' . $showUrl . '" title="' . $rows[$i]['longtitle'] . '"' . $la . '>' . $rows[$i]['menutitle'] . '</a>' . "\r\n";
$ret .= GenerateMenu($lvl, $rows[$i]['id']);
// Check for a snippet, and render it
$it = $rows[$i]['introtext'];
if($cs && IsSnippet($it)){
// if we find a snippet in the Summary field, run it, and attach it to our output
preg_match('/\[\[!?(.*)\]\]/', $it, $sm);
$ret .= $modx->runSnippet($sm[1]);
// clean up
unset($sm);
}
$ret .= ' </li>' . "\r\n";
}
$ret .= ' </ul>' . "\r\n";
}
// clean up
unset($rows);
// Check to see if we should cache it, if so, set it to cache, and apply the length of time it should be cached for: defaults to 2 hours
if($sc){
// NEED TO SET THE PLACEHOLDERS TO CACHE SOMEHOW
$modx->cacheManager->set('Navigator', $ret, $cl);
}
// return the menu
return $ret;
}
} catch(Exception $e) {
// If there was an error, make sure to write it out to the modX Error Log
$modx->log(modX::LOG_LEVEL_ERROR, '[Navigator] Error: ' . $e->getMessage());
return null;
}
}
}
The easiest solution may be pdoTools which allows you to establish caching at run time.
http://www.shawnwilkerson.com/modx/tags/pdotools/
Also, I do not believe resource placeholders are cached which is the best place to have your items cahced:
case '+':
$tagName= substr($tagName, 1 + $tokenOffset);
$element= new modPlaceholderTag($this->modx);
$element->set('name', $tagName);
$element->setTag($outerTag);
$elementOutput= $element->process($tagPropString);
break;
From lines 455-461 of https://github.com/modxcms/revolution/blob/master/core/model/modx/modparser.class.php#L455
You may notice the other tag types have:
$element->setCacheable($cacheable);
I cover the parser in Appendix D of my book. I found some issues in it in 2011 which Jason corrected.
Move toPlaceholders() to the end of your script and instead cache the array of placeholder data:
// attempt to retrieve placeholders from cache
$placeholders = $modx->cacheManager->get('Navigator');
// if not in cache, run your snippet logic and generate the data
if (empty($placeholders))) {
$placeholders = array(
'myplaceholder' => 'placeholder data'
);
$modx->cacheManager->set('Navigator', $placeholders, $cl);
}
// set placeholders for use by MODX
$modx->toPlaceholders($placeholders);
I have been trying to get the PayOne FrontEnd interface to accept the hash value from my request, to absolutely no avail. I have a support ticket open but need a solution relatively quick, so here I am.
The error returned is "Hashwert Nicht Korrekt" (Hash value incorrect).
Here is my code:
$request="authorization";
$portalid = 2017373;
$aid = 24413;
$key = "secretkeychangedforsecuritoyreasons"; // Key (configurable in the payment portal)
$id[1]= "PART_100";
$pr[1]= 2000;
$no[1] = 1;
$de[1] = "Registration Fee";
$va[1] = 19;
$amount = round($pr[1]*$no[1]);
$clearingtype = "cc";
$mode = "test";
$currency="EUR";
$reference="24393";
$customerid="24393";
$hash = md5(
$aid .
$amount .
$currency .
$customerid .
$clearingtype .
$de[1] .
$id[1] .
$mode .
$no[1] .
$portalid .
$pr[1] .
$reference .
$request .
$va[1] .
$key
);
$url="https://secure.pay1.de/frontend/?request=" . $request .
"&aid=" . $aid .
"&mode=" . $mode .
"&clearingtype=" . $clearingtype .
"&portalid=" . $portalid .
"&customerid=" . $customerid .
"¤cy=" . $currency .
"&amount=" . $amount .
"&reference=" . $reference .
"&id[1]=" . $id[1] .
"&pr[1]=" . $pr[1] .
"&no[1]=" . $no[1] .
"&de[1]=" . $de[1] .
"&va[1]=" . $va[1] .
"&hash=" . $hash;
header("Location: $url");
I have checked and re checked the docs and can find no errors in the way I am puttign it together. If I change single values like portalid, etc. it throws the appropriate error.
Any help would be appreciated.
I found the following section in the client-api-documentation:
Attention:
PAYONE Platform expects the calculated
hash
value
converted
to
lower
case;
e.g.
87dbc7c369b85b7a699adff1a2b27bab
Maybe you have some capital letter in your hash? I do an ".toLowerCase()" (in Java) on the encrypted hash.
One other option: you forgot some parameters.
on the first look i can't see the following: mid
We use the following:
$req['aid'] = 09876; // Sub-AccountID
$req['portalid'] = 6789012; // portal-ID
$req['mode'] = "live"; // Live || test
$req['request'] = "authorization"; // Request
$req['id[1]'] = $YourProductID; // e.g. articleno
$req['pr[1]'] = $singleprice;
$req['no[1]'] = $count; // count or pieces
$req['de[1]'] = $articledescription;
$req['amount'] = $summary; // price summary
$req['currency'] = "EUR";
$req['reference'] = $unique_ref.$YourProductId; //my unique is time()
$req['customerid'] = $userId;
$req['clearingtype'] = $clearing; // cc || wlt
$req['encoding'] = "UTF-8";
$req['targetwindow'] = "top";
ksort($req); //so i know its important to sort
//building the hash
foreach ($req as $key => $val) {
$req['hash'] = $req['hash'] . $val;
}
// all in md5() ... note your own payment ID
$req['hash'] = md5($req['hash'] . $YourPayOneID);
Hope it helps ;)