digital-ether 399 Nearly a Posting Virtuoso Team Colleague

The thing that get's me about template engines is that in order to be as expressive as the language they are written in, they can become quite complex and add another learning curve for the designers.

The developers have to learn the template syntax as well and know how to debug that template engine. This is another layer of complexity on their existing stack.

The former could then be almost independent of the backend language.

Most projects don't need to give the UI the ability to switch backeneds - though it does happen. Also a template is coupling your view to the syntax of the templating engine just the same as it would to PHP.

For example, if you're doing a foreach() loop in the template, you are going to use the templates foreach() like syntax. There is also property resolution ie. -> and [] in PHP objects and arrays, \ for namespaces. Conditional statements, type comparisons etc. that have to part of an expressive templating engine.

If you switch backends the backend has to support that particular template syntax.

It's impossible to totally decouple the view from the backend. To do that you have to move your templating to purely client side. So the decision lies in the needs of the project. I think there is nothing wrong with going pure PHP in the template. This is what PHP was written for in the beginning.

If the project has dedicated designers that don't want to learn PHP …

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Try using builtwith.com. It tells you a lot about the technologies websites are built on.

diafol commented: nice link +13
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

You can use proc_open() to open multiple php processes. You can open a process to a PHP file that will run the server online test. You don't have to wait for proc_open() to return, so you can run it multiple times.

If you want to read the returns async, then use stream_select(). Otherwise you can just have the php scripts called by proc_open() write to persistent storage, like a db or file with the results.

You can also use exec() to execute processes async. eg:

exec('php /path/to/server_online_test.php http://example.com &');

That would call /path/to/server_online_test.php passing it "http://example.com" as an argument. You can retrieve the argument via $argv[1]

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

The preg_replace was to just try and cover some the sql injection that mysql_real_escape_string and htmlentities doesn't cover.

More filters or escaping will NOT improve the escaping of a variable. In fact it does the opposite - makes the filter less secure. (an example of this was an XSS injection with a Google website a couple years ago).

mysql_real_escape_string() is what you use to escape strings you pass to mysql. It is the only escape you need for strings as mentioned already.

htmlentities() is the escape for strings you pass to HTML. That is what you write out to a page, and do not want HTML injection, also known as XSS.

htmlspecialchars() is the escape for strings you pass to XML. This is common for AJAX requests and prevents XML injection.

If you use the wrong filter it is useless. If you combine filters, it does not help. When using a filter or escape function you also need to know the encoding of the string being escaped, otherwise it won't work 100%. For example, you cannot use the same filter for utf-8 string as for ASCII string.

When using htmlentities() you need to specificy the encoding with the third parameter. This must be the encoding of the HTML you send to the browser.

With mysql_real_escape_string() the character encoding is taken from the database table, so it is done for you.

In any case you do not need preg_replace() as you cannot match all …

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

The $pattern must be a regular expression. It must have delimiters around the pattern, and optional modifiers after the second delimiter.

Example patterns:

"/cb/" - matches cb
"/cb/i" - matches upper and lower case cb

see the docs for preg_match. http://php.net/preg_match

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Warning: sprintf() [function.sprintf]: Too few arguments in C:\xampp\htdocs\folder\search.php on line 62
Query was empty

Are you using a PHP framework? Or a custom database class?

Whats happening is that your SQL query is being run through sprintf() function, which will try and replace the special keys that start with the '%' signs with the variables passed in. See: http://php.net/sprintf

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

It is actually harder to set up email on your localhost then your actual webserver. For one your localhost is likely windows, which doesn't have sendmail built in. The other is if you use SMTP, usually you use your servers SMTP server and your PHP script is considered to run on the local netwowrk. Many mail servers will allow local connections to the SMTP server without authentication.

The other thing is that SMTP servers do not trust IP addresses issued to regular internet subscribers (your local IP). Your local computer is also unreachable from the internet, making some verification features (spam checks) impossible to do. Your remote web server usually has an SMTP server configured for this.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

PHP 5.2.11 on Win.

Defined classes prefixed with "Spl" are:

SplFileInfo
SplFileObject
SplTempFileObject
SplObjectStorage

When enabling php_spl_types extension:

SplType
SplEnum
SplBool
SplInt
SplFloat

are added.

I'm using this to get the classes:

$classes = get_declared_classes();
foreach($classes as $class) {
   if (strpos($class, 'Spl') !== false) echo $class . "\n"; 
}

It looks like 'SplFixedArray' isn't included before 5.3.0?

chrishea commented: Very logical approach to determining the answer. Good work. +10
diafol commented: we're not worthy! +13
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Are you aware that XMLHTTPRequest can only be made to the same domain?

You need the domain you're requesting from to grant cross domain access somehow or you will have to proxy the request.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

For the first issue, where you have duplicates. What you can do is put a unique index on the user_id row. That way a duplicate creates an error and can never exist.

Do not worry about the extra load on the db when you check if an entry exists. It is a necessary part of your logic, so do it. Foremost is that your application works well.

If you have problems later on, it most likely will not be because you're checking for an existing entry. Read some posts online on "premature optimization". You can wonder about design all day if you think of every small decision and how it affects load.

On fail of the insert, you will have to figure out what went wrong. You can either change your onstoreuser to onbeforestoreuser or whatever it is called. Then do your insert before user is stored, and if it fails, return false so that the user registration fails. Then send yourself an email, or other notice or log the error somewhere for notification later.

When updating the credits row, you should check how many rows were affected in the update. If the update did not affect any rows, then something is wrong, so notify the user and yourself.

You can also hook into the user login through a plugin. When the user logs in, check if their credits row exists. If not, create it. This works for users that already exist in the db …

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Hi,

would it be difficult to let's say add a record to another table on user registration? Lets say I want to add a records how many credits the user has in jos_credits table when user registers, in other words - add record with that user id and set credits to 0 initially. When they add money to a website, they will get credits.

One thing I can think of is use database trigger, but I don't like them very much. Is there another way to do it with a component for example?

Another way to partialy solve that problem would be not to add record to a credits table, and only add it when the user deposits money. The problem is - we will have to check if there is already a record created when the user adds money, so do we have insert new or update an existing, so it is waste of recourses.

Joomla has a plugin system that will trigger certain events in the Joomla Framework.

The User plugins have events for saving user data, authentication etc.

see: http://docs.joomla.org/Reference:User_Events_for_Plugin_System#5.3.7_onAfterStoreUser

Here is a bit on creating a plugin: http://docs.joomla.org/Tutorial:Creating_a_Plugin_for_Joomla_1.5

Basically you will create a plugin which is an xml file and a php file. The PHP file contains a class that extends the plugin base base class. Then you define functions which handle the different events. You're interested in the onAfterStoreUser() method.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Thanks for moving the thread peter.

No offence also, but please give the poster the benefit of the doubt and be a bit more careful with wording such as "not 24/7 coding service" as it may be taken as impolite by some.

Many are not well versed in forum etiquette and though they may seem rude to seasoned forum posters, they really are not trying to be.

peter_budo commented: Will keep that in mind ;) +16
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Simple example of chat. Should start you off...

<form method="post">

<?php

if (isset($_POST['chat']) && trim($_POST['chat'])) {
  file_put_contents('chat.txt', $_POST['chat'] . "\n", FILE_APPEND);
}

echo @implode('<br />', @file('chat.txt')) . '<br />';


?>

<input name="chat" />
<button type="submit">Send</button>
<button type="submit">Refresh</button>

</form>

Note: this does not have users, rooms, does not update automatically, and has no security measures. If you ask for each of this individually I'm sure many would love to help you code it.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

The PHP Language reference has details on what a function and class is:
http://www.php.net/manual/en/langref.php

It also explains most the other features of PHP. If want to learn PHP that is the best place to start.

Functions

The function is a grouping of statements (lines of code).

For example the following statements:

$name = 'mary';
$gender = 'girl';

if ($gender == 'girl') {
  $line = $name . ' had a little pony.';
} else if ($gender == 'boy') {
  $line = $name . ' had a little horse.';
}
echo $line;

Can be grouped together into a function so it can be reused:

getSentence('mary', 'girl');
getSentence('peter', 'boy');

function getSentence($name, $gender) {
  if ($gender == 'girl') {
    $line = $name . ' had a little pony.';
  } else if ($gender == 'boy') {
    $line = $name . ' had a little horse.';
  }
  echo $line;
}

Notice the two function calls:

getSentence('mary', 'girl');
getSentence('peter', 'boy');

These two statements run the whole block of code inside the getSentence function and pass it the variables $name and $gender.
With the first function $name = 'mary' and $gender = 'girl' and in the second $name = 'peter' and $gender = 'boy'.

So the main benefit of functions is that you have grouped code for reuse, allowing the passing of different values for the variables needed by the function. These variables are called the function parameters.

Another benefit of having the code grouped is easier readability. You …

Zagga commented: You couldn't ask for a fuller explaination. Love it! +2
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Try debugging your code. Make sure you're getting the correct list/array of passwords.

eg:

$var_list = explode("\n",$var_data);
var_dump($var_list);

or:

print_r($var_list);

Zero13 recommended using:

$var_list = explode("\r\n",$var_data);

Instead since Windows line breaks are \r\n instead of just \n in Linux. However, to work with both Windows and Linux you need something like:

$var_list = explode("\n",$var_data);
// trim each value in the data
$var_list = array_map('trim', $var_list);

However, if spaces mean something in each line you need to only trim the \r character.

Just a note, instead of using:

echo ( '<meta http-equiv="REFRESH" content="0;url=WinthropPoll01.html">');

You can use:

header('Location: WinthropPoll01.html');

That sends a HTTP redirect which is followed without displaying any content. However, that only works if you have yet to display any content at all.

To solve that you usually use output buffering to buffer your content (see: ob_start() ) or you can test for output using headers_sent().
http://us2.php.net/manual/en/function.headers-sent.php

eg:

if (!headers_sent()) {
   header('Location: WinthropPoll01.html');
} else {
   echo ( '<meta http-equiv="REFRESH" content="0;url=WinthropPoll01.html">');
}
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

I wrote a Class to read sessions from the PHP session files:
http://www.daniweb.com/code/snippet317107.html

Thought it would be useful to others trying to do the same.

Aamit commented: Thanks for greate help +0
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

The above classes provide an interface for reading the PHP session data.

PHP alone only gives you access to the current users session. This class allows you to read all session files, and thus allow you to read session data across different users.

This may be useful if you want to copy, backups session data, or transfer to a different format/handler etc..

At the moment it only reads file based session handling, with PHP doing the serializing and handling (the default setting). It does not support other session handlers or serializers.

You can extend the base abstract class for different handlers and serializations.

Example usage:

require 'FileSessionData.php';

// instantiate the file session reader
$FileSession = FileSessionData::singleton();

// get all saved session ids
$sess_ids = $FileSession->getIds();

// loop through each session id on the server and show session data
foreach($sess_ids as $id) 
{
  // get the session data
  if ($data = $FileSession->get($id))
  {
    // dump session array
    dumper($data);
    // dump serialized session
    dumper(FileSessionData::encode($data));

    exit; // lets limit to just one for testing
  }
}




/**
 * Dump utility
 * @param Object
 */
function dumper($data)
{
  echo '<pre>' . print_r($data, true) . '</pre>';
}
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Do a

var_dump($json);

to see the structure.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

The two main things here is:

1) Saving the form field values added by the user
2) Returning to the form without the "resend post" message

Saving the form field values added by the user
The only way to save the values effectively is to save them server side (or client side) and populate the form with those values when returning the user to the form.

So you can save the form values when the user submits, to their session for instance.

Returning to the form without the "resend post" message
To return without a post message, you have to use a direct link, instead of the browser back feature.
The other way to do it, is impose a HTTP redirect in between the form processing page, and the actual page displayed to the user.

So for instance when the user submits the form at form.php, you validate it on a page called validate.php, and then redirect to a page called results.php. That way, when the user hits the back button, they are taken directly back to the form.php page bypassing the process.php form submit.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

It doesn't matter if you use pear or mail(), an email server configured to deny senders that do not have accounts on the mailserver will not send email with different sender addresses.

If your mail server sends email with sender addresses with accounts not on the server, then you essentially have an open relay, which will likely hinder your ability to send email as it will be marked spam, and also invite spammers to use your mail server.

diafol commented: Aha - sense at last. Thought I was losing the plot. +6
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Since time() is a timestamp (number of seconds since Epoch), there are only 60*60 different values of time in one hour.

Here is an example of generating a more random value:

/**
	 * Generate a random hex based token
	 * @return String
	 * @param $length Int[optional]
	 */
	public static function generateToken($length = 40)
	{
		$token = array();
		for( $i = 0; $i < $length; ++$i )
		{
			$token[] =	dechex( mt_rand(0, 15) );
		}
		return implode('', $token);
	}

That generates a hex of 40 digits. See: http://www.bucabay.com/web-development/secure-password-hashing-storage-ph/ for the full code.

Rkeast commented: Sorry I didn't understand fully what you meant before. +1
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Use regular expression:

eg:

$name = 'S-KHI-1233';

$name = preg_replace("/[^0-9]/", '', $name);
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Spaces, tabs, newlines are ignored by the PHP interpreter. So they are optional. :)

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Hi,
I am trying to read the content of url.
when manually i put url in browser

link : http://www.mvnforum.com/mvnforum/viewmember?member=pbmissions
it opens.

but using code

$homepage = file_get_contents('http://www.mvnforum.com/mvnforum/viewmember?member=pbmissions');
echo $homepage;

Warning: file_get_contents(http://www.mvnforum.com/mvnforum/viewmember?member=pbmissions) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 503 Service Unavailable in C:\xampp\htdocs\test.php on line 2

What is problem ?
How to solve this?

There is nothing wrong with your code. It is just the response from the server:

HTTP/1.1 503 Service Unavailable

That means that the server is unavailable. Usually this is a temporary error.

NB: if the allow_url_fopen setting is preventing http requests you'd get a: "http wrapper disabled etc.." error

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Having PHP handle static files, such as JS and CSS and gzipping them on the fly is inefficient.

A better approach is to have PHP write a gzipped version of the static file to the filesystem.

You can check on each request if the file has changed, and then re-write the gzipped version if it has.

eg: simple example

function getGzippedPath($path) {
   $ext = substr($path, strrpos($path, '.'));
   $path_gz = dirname($path).'/'.md5($path).'.gz.'.$ext;

   if (!file_exists($path_gz) || filemtime($path) > filemtime($path_gz)) {
      // file has been modified or never created
      ob_start ("ob_gzhandler");
      readfile($path);
      $gz = ob_get_clean();
      if (file_exists($path_gz)) unlink($path_gz);
      file_put_contents($path_gz, $gz);
   }
   return $path_gz;
}

This would take a file path such as /path/to/file.js and write a gzipped version to '/path/to/'.md5('/path/to/file.js').'.gz.js' if the gizzped version does not exist, or if it is the gzipped is older.

almostbob commented: Thanks, this is better, +2
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

i want to pass a youtube code like
http://www.youtube.com/watch?v=NMAYr709-9Y&feature=dir
and it return me the embed code.........!! how can i do that with php and curl........!!

This it the embed code for that particular page:

<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/NMAYr709-9Y&hl=en_US&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/NMAYr709-9Y&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>

Notice the only unique thing is: NMAYr709-9Y

So you can just generate that embed code without having to make a http request to youtube.

eg:

// url of video
$url = 'http://www.youtube.com/watch?v=NMAYr709-9Y&feature=dir';

// we get the unique video id from the url by matching the pattern
preg_match("/v=([^&]+)/i", $url, $matches);
$id = $matches[1];

// this is your template for generating embed codes
$code = '<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/{id}&hl=en_US&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/{id}&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>';

// we replace each {id} with the actual ID of the video to get embed code for this particular video
$code = str_replace('{id}', $id, $code);
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

My friend and I are working on an Internet bot. We want to make a bot that given a website, would index into a table.

Example --

Given the website: www.daniweb.com

Add to table:

www.daniweb.com/c++
www.daniweb.com/c++/forum
www.daniweb.com/java
etc...

Any suggestion on how to do this?

To explain how this is done:

First you make a http request to the page you want to parse.

eg:

$url = 'http://example.com/';
$content = file_get_contents($url);

Then you parse the HTML. A good option is using DOMDocument.
http://docs.php.net/manual/en/domdocument.loadhtml.php

The loadHTML() function of DOMDOcument will parse HTML into a DOM Tree. You can then use DOM methods, or hand the DOM over to SimpleXML if you find that easier.

$url = 'http://example.com/';
$content = file_get_contents($url);
$Dom = DOMDocument::loadHTML($content);
// you can traverse the DOM
$Xml = simplexml_import_dom($Dom);
// or use the simpleXML methods, which may be simpler

You can also just use regular expressions.

$url = 'http://example.com/';
$content = file_get_contents($url);

// parse what you want with a regular expression
$regex = '/href=["\'](.*?)["\']/i';
preg_match_all($regex, $content, $matches);

var_dump($matches);
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

You can send SMS for free to most carriers by sending an email to their Email to SMS gateway.

A list of carriers is here:
http://en.wikipedia.org/wiki/List_of_carriers_providing_SMS_transit

I wrote a class based on this a while ago but never got around to finishing it:

If you're interested in finishing it, here it is:

<?php
/**
 * Send SMS via Email to SMS gateways
 * 
 * Please note that the list of carreirs is UTF-8 encoded. ie: Mexico != México
 * 
 * @author gabe@fijiwebdesign.com
 * @link http://www.fijiwebdesign.com/
 */
class email2sms {
	/**
	 * A list of the major Phone carriers and their Email 2 SMS gateway syntax
	 * Compiled from: http://en.wikipedia.org/wiki/List_of_carriers_providing_SMS_transit
	 */
	protected static $carriers = array(
		array("Airtel", "Andhra Pradesh, India", "#@airtelap.com"),
		array("Airtel", "Karnataka, India", "#@airtelkkk.com"),
		array("Alaska Communications Systems", "USA", "#@msg.acsalaska.net"),
		array("Alltel Wireless Verizon Wireless", "USA", "#@text.wireless.alltel.com,#@mms.alltel.net"),
		array("aql", "UK", "#@text.aql.com"),
		array("AT&T Wireless", "USA", "#@txt.att.net,#@mms.att.net"),
		array("AT&T", "USA", "#@mmode.com"),
		array("AT&T Mobility", "USA", "#@mms.att.net,#@txt.att.net,#@cingularme.com"),
		array("AT&T", "USA", "#@page.att.net"),
		array("Bell", "Canada", "#@txt.bell.ca,#@txt.bellmobility.ca"),
		array("Boost Mobile", "USA", "#@boostmobile.com"),
		array("Bouygues Télécom (company)", "France", "#@mms.bouyguestelecom.fr"),
		array("[[Loop_Mobile_India|Loop] (BPL Mobile)", "Mumbai, India", "#@bplmobile.com"),
		array("Cellular One", "USA", "#@mobile.celloneusa.com"),
		array("Cingular", "USA", "#@cingular.com"),
		array("Centennial Wireless", "United States, Puerto Rico, U.S. Virgin Islands", "#@cwemail.com"),
		array("Cincinnati Bell", "Cincinnati, Ohio, USA", "#@gocbw.com,#@mms.gocbw.com"),
		array("Claro", "Brasil", "#@clarotorpedo.com.br"),
		array("Claro", "Nicaragua", "#@ideasclaro-ca.com"),
		array("Comcel", "Colombia", "#@comcel.com.co"),
		array("Cricket", "", "#@mms.mycricket.com,#@sms.mycricket.com"),
		array("CTI Móvil Claro", "Argentina", "#@sms.ctimovil.com.ar"),
		array("Emtel", "Mauritius", "#@emtelworld.net"),
		array("Fido", "Canada", "#@fido.ca"),
		array("General Communications Inc.", "Alaska", "#@msg.gci.net"),
		array("Globalstar satellite", "", "#@msg.globalstarusa.com"),
		array("Helio", "", "#@myhelio.com"),
		array("Iridium", "", "#@msg.iridium.com"),
		array("i-wireless (Sprint PCS)", "", "#@iwirelesshometext.com"),
		array("Mero Mobile", "Nepal", "#@sms.spicenepal.com"),
		array("MetroPCS", …
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Note: There are 3 hashing methods with 8 characters adler32/crc32/crc32b I am assuming none of these should be used? That begs the question but why were they created in the first place?
I gather any other hashing methods are fine as the next shortest one is 32 characters!

adler32 and crc32 were developed for a different purpose then security. They are used more for verifying data integrity or error detection.

They do not provide means to secure against intentional data modification, since this wasn't the design goal.

Wikipedia explains all this:
http://en.wikipedia.org/wiki/Adler-32
http://en.wikipedia.org/wiki/Cyclic_redundancy_check

As also mentioned, the hashes produced are short enough that all possible hashes can be computed by a single computer in minutes.

Notice that the hashes used today are much longer then those used in the past. We have to keep using longer and longer hashes because computers are becoming more efficient.

The only reason adler and crc is used for data integrity instead of larger hashes is because they are faster, yet do the job of error detection very well.

Anyways, I have made a dehasher that can dehash up to 6 digits depending on what characters are to be dehashed and time allowed. You can grab a copy of the SHA1 dehasher from the attachment on this post to see how insecure SHA1 is IMO. Enjoy dehashing the >=6 digit hashes.

You might be interested in the list of top password crackers published by …

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

I gather what you are saying " Atli ", but if your rehashing a hash from crc32b it is still valid, like as you stated your still making an xxx hashing not shorten the length of a hash but like you stated it would be absurd to use crc32b as your only means of protection.

Salt I can understand, I guess it just comes down to personal taste, depends how much junk you want to add to the end of the string I guess to make it that unique?

At this rate why not quadriple whirlpool and salt a hash, I guess it comes down to the point of meaningful and meaningless code dependent on the coders opinion... lol

CRC32 should NOT be used at all. Not as the last hash output, or before you hash it again with a secure hash. Just not at all.

Even if you take a crc32 hash and rehash it with sha256. It doesn't strengthen the crc32 hash.
The number of different hashes CRC32 can produce is only 2^32 = 16^8 = 4.294.967.296.

So you're basically reducing the number of different hashes someone needs to check, down to 4.294.967.296. This only takes a few minutes on an average PC. If you used a precomputed table of CRC32 hashes, it would take only a few seconds.

The reason they only have to check that number, is that CRC32 thus only produces a subset of the sha256 hashes (4.294.967.296 unique SHA1 …

OmniX commented: Detailed response, Thankyou! +2
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

why not just use the username or one of the existing data base fields as a salt? that way it will be unique for each password.

I was reading up on salts and the consenses is that as long as they are used to stop precomputation attacks (aka rainbow tables, etc) the length required is meaningless only the value of the salt, which should be randomly constructed.

This statement correct?

PS: now dont be trival and start if my salt is only 1,2,3 charcters salt should be 5+ randomly constructed and stored in a database for retrieval.

@OmniX The length of the salt does matter. The salt should be random, yes, but it should also be long enough to make the precomputation attack infeasible.

I've also read those statements that the salt length does not matter, and this is incorrect. See http://en.wikipedia.org/wiki/Password_cracking#Salting

It states that the 12 bit salts used in earlier unix is not long enough to prevent precomputation. BCrypt for example uses a 128 bit salt. A comparatively complex salt in ASCII characters A-Za-z0-9 is about 23 chars.

There are many 14 character long rainbow tables available. So if a salt is not 14 characters, it is open to precomputation attacks by anyone wanting to do so.

@leviathan185 the username is not random enough and also too short.

Anyways what I gathered from 'digital-ether' alone crc32 is faulty but if used in conjunciton with another hashing algorithm, it is fine?

CRC …

Atli commented: Nicely put. +3
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

A hash is meant to be one way. There is no way to actually guarantee it. True one-way functions are only theoretical at this point.

Not that I don't agree with you; that hashes should be considered one-way. Just pointing out that it is not an absolute truth, but rather a practical truth. We could very well see some of the more popular hashing algorithms being "broken" in the future.

Wouldn't you just love to prove it?
http://en.wikipedia.org/wiki/Millennium_Prize_Problems
I think I'll try and solve it tonight. Or maybe just buy a lottery ticket, better chance of winning that.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague
function HASHITBAY_BE($toHash)
{
   $maxLength = 42; //maximum length of the salt
   $hashMethod = 'whirlpool' //encryption method...
   $saltLength = strlen($toHash)*3;
   if($saltLength > $maxLength)
      $saltLength = $maxLength;
   if($saltLength < 10)
      $saltLength = 10;
   $salt = saltGen($saltLength);
   $hash = hash($hashMethod, $toHash . $salt);
   $hash = substr($hash, $saltLength-10);
   $hash = $salt . $hash;
   return $hash;
}

The cool thing about using this method is that, even if the hacker gets access to your database, AND your source code, it's nearly impossible for him to retrieve your original data, as he'd have to already know the length of the password (or whatever the data is), in order to retrieve the salt.

@chaines51 not to be nitpicky but I would not rely on someone not being able to guess the length of the password as a way to increase security. It is even easier to guess the length of a password, then just one char in a password. The idea itself is great, however, I think the practical implication is not that useful.

Based on the max and min length of the salt, it can only be 32 different lengths. But knowing that most passwords are around 6-8 chars, you are only left with about 2 or 3 lengths to guess on average, making it negligible.

I'd also make sure the salt is at least 20 chars. The rainbow tables of 14 chars are common (lookup for an input of combined length of 14 chars is possible). So I'd stay on the safe side …

nav33n commented: Thanks for the informative post digital :) +5
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Anyone who knows how to apply this in php scripting? the scripts in this site can be xecuted in mysql console but I can't get it working in php script in the website im studying.
I want to create a tree like this: http://sitepointstatic.com/graphics/sitepoint_numbering.gif

The examples at http://www.sitepoint.com/print/1105/ should do...

digital-ether 399 Nearly a Posting Virtuoso Team Colleague
include_once('session.php');
include_once('config.php');
$userid = $_SESSION['userid'] ;
$uname = $_GET['uname'];
 $query= "call sp_active('$uname','$userid',@u_active)";

$result = mysql_query($query) or die('query_error'.''.mysql_error());
  if($result)
  {
    header('location:vagent.php');
  }

simple php code.. but still throwing Cannot modify header information - headers already sent by

i have also use ob_start(); but of no use

Are you using ob_start() before any PHP code?

eg:

<?php
ob_start();
 include_once('session.php');
include_once('config.php');
// .. etc...
?>

Also make sure there isn't any spaces or newlines before the call to ob_start();

The other possible problems is if you have a UTF BOM added by your editor, if you're using windows.
http://en.wikipedia.org/wiki/Byte_order_mark

You can detect this with PHP by making a HTTP request (eg: file_get_contents()) to the page, and checking if the first byte matches unicode point U+FEFF.

Another possibility is if you have errors in your PHP build, or configuration, that makes it spit out an error before PHP scripts are interpreted.

Both of these would cause header() to fail even if ob_start() is used since they occur before any PHP code you write.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Looks great. I modified the class I wrote a bit after looking at your code.

Just a few suggestions:

You could optimize the string concatenation.

$buffer .= hash($algo, $input . $salt);

A lot of the execution time is the concatenation of the $buffer string.

If you use an array however, it becomes negligible. I believe the reason is the whole string has to be copied/destroyed in memory each time you append to it. Arrays are mutable so appending would not create a copy.

You could calculate the number of iterations you'll need by dividing the memory usage (in bytes) by the length of the hash. That way you also don't have to re-check the length of the string.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Thought I'd write an example:

note: for PHP4 just remove the "public static" in front of each function declaration.

The class:

/**
 * Generate cryptographic Hashes for passwords 
 * 
 * Features: 
 * 	Harderned against precomputation attacks like rainbow tables (using salt)
 * 	Harderned against brute force and dictionary attacks (using key stretching, large memory usage and an optional secret key)
 * 
 *  http://en.wikipedia.org/wiki/Password_cracking
 *  
 *  Note: for PHP4 and lower, just remove the "public static" before function declaration
 * 
 * @author gabe@fijiwebdesign.com
 * @link http://www.fijiwebdesign.com/
 * @version $Id$
 */
class Password_Hash 
{

	/**
	 * Generate the Hash
	 * @return String
	 * @param $password String
	 * @param $salt String[optional]
	 * @param $iterations Int[optional]
	 * @param $secret String[optional]
	 */
	public static function generate($password, $salt = null, $iterations = 10000, $hash_function = 'sha1', $secret = '') 
	{
		$salt or $salt = self::generateToken();
		$hashes = array();
		$hash = $password;
		// stores a sequence of 10000 unique hashes in memory
		$i = $iterations;
		while(--$i) 
		{ 
			$hash = $hashes[] = $hash_function($hash.$salt.$secret);
		}
		// hash the 10000 unique hashes into a single hash
		$hash = $hash_function(implode('', $hashes).$salt.$secret);
		return implode(':', array($hash, $iterations, $hash_function, $salt));
	}
	
	/**
	 * Verify a password meets a hash
	 * @return Bool
	 * @param $password String
	 * @param $hash String
	 * @param $secret String[optional]
	 */
	public static function verify($password, $hash, $secret = '')
	{
		list($_hash, $iterations, $hash_function, $salt) = explode(':', $hash);
		return ($hash == self::generate($password, $salt, $iterations, $hash_function, $secret));
	}
	
	/**
	 * Generate a random hex based token …
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

I am currently building an online system, it has come to the point to think about securing peoples passwords. How ever, for admin reasons I was wondering if it was possible to decode the encoded password, I believe this is not possible with md5 but hoping there is another method?

Any help would be geat, also any other information regarding safety, thanks.

There really is no reason to use 2 way encryption on passwords. Retrieving the password is not the concern, gaining access to their account is. So if the user forgets their password, send them a token through email to set a new password.

Use secure hashes to store the passwords. Add a long salt before hashing, and hash that password and salt together 100,000 times or so. Make sure you use quite a bit of memory in the process.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Sorry for resurrecting an old thread. But it was referenced recently and I thought I'd add to it.

crc32b should not be used with passwords as it is an insecure hash function.
http://en.wikipedia.org/wiki/Cyclic_redundancy_check

It also generates hashes that are only 8 hexadecimal (base 16) digits long. Thus you have less then 16^8 possible hashes. (or less then 10 digits decimal)

A simple brute force such as:

$hash = hash('crc32b', hash('whirlpool', 'some password ^#d@C~'));
while($hash != hash('crc32b', $n)) { $n++; }
echo $n;

will produce a collision for any crc32b hash within an hour on an average PC. Using crc32b basically makes the original hashing function (whirlpool in this example) useless.

Whirlpool produces a 128 digit hexadecimal. Thus you should keep the whole hash in order to preserve its effectiveness against attacks. Rehashing a whirlpool hash with another hash that produces a shorter hash probably isn't a good idea. If you're doing it to save space, there are better alternatives.
http://www.bucabay.com/php/base-conversion-in-php-radix-255/

You should also always salt passwords before hashing to make rainbow tables (and other precomputation attacks) unfeasible.
http://en.wikipedia.org/wiki/Rainbow_table

A rainbow table, is just a list of possible passwords, and their corresponding hashes. So it can be thought of as a simple database table with one column for the password, and the other for its hash. However, generating all the possible passwords for longer passwords, and more characters, requires a lot of space. So rainbow tables use a time-space …

Atli commented: Excellent post. Using crc32b seemd a bit odd. Now we know :) +3
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Here is the tutorial on how to get seeking possible in the JW Player.
http://www.longtailvideo.com/support/tutorials/HTTP-Video-Streaming

This allows seeking to a not yet buffered part of the video. If you're wondering why you can't just do this with regular HTTP "range" headers see: http://www.longtailvideo.com/support/forum/Feature-Suggestions/8167/streaming-via-standard-HTTP-byte-ranges
and http://kb2.adobe.com/cps/403/kb403030.html

I haven't tried the other players, but I'm sure they have something similar. The only way to do it in a standard way, would be to use a media streaming server that Flash understands, like Red5.
http://osflash.org/red5

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Try Debut Video Capture Software. It was free and did more than I expected it too.

In the tutorials, make sure you are using proper practices. I don't want to watch them and then see stuff that is wrong.

I just tried the video capture and the other tools they have, that is some really good stuff. Thanks for recommending it.

Btw, the link is:
http://www.nchsoftware.com/

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Does anyone know of a Ubuntu ogv to (avi or wmv) file converter. If such converter does not exist then are there any desktop record utilities for windows that record both part of the screen that I select and record the microphone at the same time for free? Just needs one of those two programs to be able to finish the first video tutorial. Thanks.

For transcoding media files you're best bet is FFMpeg, http://en.wikipedia.org/wiki/FFmpeg

You can invoke it from the command line. If you want a graphical interface, VLC is also Open Source and uses FFMpeg internally.
http://www.videolan.org/vlc/

For recording try camstudio: http://camstudio.org/

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

A tutorial on how to create your first PHP page. A single step by step, that would be the easiest way to start a total noob on PHP.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

You can also try just adding a simple array in a php file, then checking it with inarray($array, $username) in an if.
Another option would be to do an sql query:

INSERT INTO `users` ... WHERE (SELECT id FROM `invalidusers` WHERE `username` = `{$username}` IS NULL)

You can't place a WHERE clause inside a SELECT statement.

http://dev.mysql.com/doc/refman/5.1/en/insert.html

However, you can do the SELECT and then INSERT if needed.

SELECT 1 FROM `invalidusers` WHERE `username` = `{$username}` LIMIT 1

Then insert if the username if no result was returned.

You could also make sure you don't have a duplicate username, or restricted one in a single query:

SELECT 1 FROM `invalidusers` WHERE `username` = `{$username}` LIMIT 1
UNION
SELECT 1 FROM `users` WHERE `username` = `{$username}` LIMIT 1

It would probably be better however, if you have a unique index on the username column.

That way you can just insert the usernames you don't want to be used into the users table before hand.

Any inserts of existing usernames during registering, will cause a duplicate entry, and thus return an errror. You can catch the error in PHP in give the user the message that their username is a not allowed.

For checking before hand, you just do:

select id from users where username = '$username' LIMIT 1

You can also have a column named "restricted" if you want to convert an existing registered username to a restricted one later on. Like someone …

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Those are all pretty much WAY overkill for what he needs. He's just trying to hit an API but the API writers evidently like their job too much and wrote the description in an extremely overtechnical way.

I find the stream_context_create() function simpler then cURL since you don't have to remember or look up all those CURLOPT_* constants.

// the xml to send
$xml = 'your xml payload';

// build your http request
$context = stream_context_create(array( 
    'http' => array( 
      'method'  => 'POST', 
      'header'  => "Content-type: text/xml\r\n", 
      'content' => $xml, 
      'timeout' => 10, 
    ), 
  )); 

// send it
  $resp = file_get_contents('http://xmldev.dotwconnect.com/request.dotw', false, $context);
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

PHP5+, you can also use the stream functions.
http://www.php.net/manual/en/book.stream.php
http://www.php.net/manual/en/function.stream-socket-client.php

or the similar fsockopen() in PHP4:
http://www.php.net/fsockopen

With both of these you will create the raw HTTP request to send over TCP. However, if you need something more abstracted like cURL, you can use fopen(), with stream_context_create() in PHP5:
http://www.php.net/manual/en/function.fopen.php
http://www.php.net/manual/en/function.stream-context-create.php

There are also many HTTP libraries based on fsockopen and stream_socket_client. You can use these or follow their examples.
http://pear.php.net/package/HTTP

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

I can't really do much to edit your function because it has so many elements I haven't seen before.

It is actually very basic.

The only odd operations used are:

% - modulo or remainder
chr() - return the character represented by a number in ASCII table
floor() - round down the float to an int

The modulo returns the remainder after dividing

eg: 5%2 = 1
ie: 5/2 = 2 remainder 1

chr(96) = a
The letter a is represented by the number 96 in ASCII

Something like:

$chr = array(96=>'a', 97=>'b' ... 255);
so chr(96) = $chr[96];

And floor just removes everything after the decimal point.

eg: 5/2 = 2.5
floor(2.5) = 2


Here is the function with comments:

/**
 * Convert Decimal to a base less then 255 comprised of ASCII chars
 *
 * @param Int $num
 * @param Int $base (2-255)
 * @return ASCII String
 */
function base255($num, $base = 255) {
 	// remove the negative sign by multiplying by -1 if $num is negative
	if ($num < 0) $num = -$num;
	// an array to hold the digits of the new number
	$ret = array();
	// while the number is larger then our base, we just keep dividing it by the base
	while($num > $base) {
		// get the remainder after dividing by the base
		$rem = bcmod($num, $base);
		// divide by the base to move up …
iamthwee commented: liking it +22
digital-ether 399 Nearly a Posting Virtuoso Team Colleague
$creation_salt = sha1($username.':'.time());

This salt is way to easy to guess. Considering time() is a number of seconds, there are only 60*60 in an hour, and 60*60*24 in an hour: 86400 possible salts in one your.

digital-ether 399 Nearly a Posting Virtuoso Team Colleague

Something like this should work:

/**
 * Return html numeric entities encoded string
 */
String.prototype.toHtmlEntities = function() {
	return this.replace(/[^a-z0-9\.\-\_\s\t]/ig, function(c) {
		return '&#'+c.charCodeAt(0)+';';
	});
};

Example:

'<div>This & that</div>'.toHtmlEntities();

It replaces every non-alphabetic and numeric character (excluding a few defined in the regex pattern) with their character codes.

serkan sendur commented: good +9
digital-ether 399 Nearly a Posting Virtuoso Team Colleague

I just tried varbinary like before and again varbinary didn't work however I tried blob which I have never heard of before and it worked! Also the bz library works but won't decompress. So using the method you have described how can I decompress the result?

Which bz library? Do you mean zlib? Is this in mysql or PHP?

You can just decompress the result in the SQL query:

SELECT uncompress(test) as test FROM `table` WHERE `compressed` = compress('test')

This should give you the column test in decompressed form.

Note:

I wouldn't use:

SELECT * FROM `table` WHERE UNCOMPRESS(`column`)="abcd"

The reason is that you'll run uncompress() on each row in the database table.
You will also be unable to use any index made on that column.

If you use:

`column`= COMPRESS("abcd")

Then you only have to compress the input "abcd" once. You will also be able to use indexes made on the `column` column since you're comparing directly.

cwarn23 commented: Excellent Code +6