auto
  +   lY>eJ}@?q1h߿^m_I|+ .Q    /*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2016 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Stefan Esser <sesser@php.net>                                |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#include "php.h"

/* This code is heavily based on the PHP md5 implementation */ 

#include "sha1.h"
#include "md5.h"

PHPAPI void make_sha1_digest(char *sha1str, unsigned char *digest)
{
	make_digest_ex(sha1str, digest, 20);
}

/* {{{ proto string sha1(string str [, bool raw_output])
   Calculate the sha1 hash of a string */
PHP_FUNCTION(sha1)
{
	char *arg;
	int arg_len;
	zend_bool raw_output = 0;
	char sha1str[41];
	PHP_SHA1_CTX context;
	unsigned char digest[20];
	
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
		return;
	}

	sha1str[0] = '\0';
	PHP_SHA1Init(&context);
	PHP_SHA1Update(&context, arg, arg_len);
	PHP_SHA1Final(digest, &context);
	if (raw_output) {
		RETURN_STRINGL(digest, 20, 1);
	} else {
		make_digest_ex(sha1str, digest, 20);
		RETVAL_STRING(sha1str, 1);
	}

}

/* }}} */


/* {{{ proto string sha1_file(string filename [, bool raw_output])
   Calculate the sha1 hash of given filename */
PHP_FUNCTION(sha1_file)
{
	char          *arg;
	int           arg_len;
	zend_bool raw_output = 0;
	char          sha1str[41];
	unsigned char buf[1024];
	unsigned char digest[20];
	PHP_SHA1_CTX   context;
	int           n;
	php_stream    *stream;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|b", &arg, &arg_len, &raw_output) == FAILURE) {
		return;
	}
	
	stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS, NULL);
	if (!stream) {
		RETURN_FALSE;
	}

	PHP_SHA1Init(&context);

	while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
		PHP_SHA1Update(&context, buf, n);
	}

	PHP_SHA1Final(digest, &context);

	php_stream_close(stream);

	if (n<0) {
		RETURN_FALSE;
	}

	if (raw_output) {
		RETURN_STRINGL(digest, 20, 1);
	} else {
		make_digest_ex(sha1str, digest, 20);
		RETVAL_STRING(sha1str, 1);
	}
}
/* }}} */


static void SHA1Transform(php_uint32[5], const unsigned char[64]);
static void SHA1Encode(unsigned char *, php_uint32 *, unsigned int);
static void SHA1Decode(php_uint32 *, const unsigned char *, unsigned int);

static unsigned char PADDING[64] =
{
	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

/* F, G, H and I are basic SHA1 functions.
 */
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) ((x) ^ (y) ^ (z))
#define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
#define I(x, y, z) ((x) ^ (y) ^ (z))

/* ROTATE_LEFT rotates x left n bits.
 */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

/* W[i]
 */
#define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
	(x[i&15]=ROTATE_LEFT(tmp, 1)) )  

/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
 */
#define FF(a, b, c, d, e, w) { \
 (e) += F ((b), (c), (d)) + (w) + (php_uint32)(0x5A827999); \