<?php 

function generateDigestHash($digest, $password, $base_url, $requestMethod)
{
	$ha1 = md5($digest['username'] . ':' . $digest['realm'] . ':' . $password);
	// HA2 calcaulated the same if even optional quality of protection is not in use.
	// HA2 = MD5( requestMethod:URI )
	if($base_url == '' && $digest['uri'] == '' && $digest['qop'] != '')
	{
		$ha2 = md5($digest['requestMethod'] . ':""');
	}
	else
	{
		$ha2 = md5($digest['requestMethod'] . ':' . $base_url . $digest['uri']);
	}

	if( isset($digest['qop']) && $digest['qop'] == '')
	{
		// qop is undefined
		// RESPONSE = MD5( HA1:nonce:HA2 )
		if(!isset($digest['algorithm']))
		{
			$digest['algorithm'] = 'md5';
		}
		$response = md5( $ha1 . ':' . $digest['nonce'] . ':' . $ha2);
		$digest_reponse = 'username="' . $digest['username'] . '", realm="' . $digest['realm'] . '", nonce="' . $digest['nonce'] . '", uri="' . $base_url . $digest['uri'] . '", response="' . $response . '", algorithm="' . $digest['algorithm'] . '"';
		if(isset($digest['opaque']) && $digest['opaque'] != '')
		{
			$digest_reponse .= ', opaque="' . $digest['opaque'] . '"';
		}

	}
	else if ( isset($digest['qop']) && $digest['qop'] == 'auth')
	{
		// qop is in use
		/*
			nonce-count
			This MUST be specified if a qop directive is sent (see above), and
			MUST NOT be specified if the server did not send a qop directive in
			the WWW-Authenticate header field.  The nc-value is the hexadecimal
			count of the number of requests (including the current request)
			that the client has sent with the nonce value in this request.  For
			example, in the first request sent in response to a given nonce
			value, the client sends "nc=00000001".  The purpose of this
			directive is to allow the server to detect request replays by
			maintaining its own copy of this count - if the same nc-value is
			seen twice, then the request is a replay.   See the description
			below of the construction of the request-digest value.
			*/
		if(!isset($digest['nc']))
		{
			$digest['nc'] = 0;
		}
		$digest['nc'] ++;
			
		/*
		 cnonce

		 a client created nonce value
		 cnonce="0a4f113b"
			*/
		if(!isset($digest['cnonce']))
		$digest['cnonce'] = uniqid();
			
		// RESPONSE = MD5( HA1:nonce:nc:cnonce:qop:HA2 )
		$toDigest = sprintf("%s:%s:%08d:%s:%s:%s", $ha1, $digest['nonce'], $digest['nc'], $digest['cnonce'], $digest['qop'], $ha2);
		$response = md5( $toDigest );

		$digest_reponse = sprintf('username="%s", realm="%s", nonce="%s", uri="%s", qop=%s, nc=%08d, cnonce="%s", response="%s", opaque="%s"',
			$this->user,
			$digest['realm'],
			$digest['nonce'],
			$base_url . $digest['uri'],
			$digest['qop'],
			$digest['nc'],
			$digest['cnonce'],
			$response,
			$digest['opaque']
		);
	}
}