
namespace crypt;

class hash{
	ctor( cryptContent,algid = 0x8003/*_CALG_MD5*/ ){ {
		this.cryptContent = cryptContent;//防止析构 
    	var ret,hHash = CreateHash( this.cryptContent.hCryptProv,algid,0,0 );
		if (!ret) {  
			return null;
		}
		this.handle = hHash;
		..table.add_gc(this,"destroy");
	} }; 
	getValue = function () { 
		var ret,size = GetHashParamByInt(this.handle, 0x4/*_HP_HASHSIZE*/, 4, 4, 0); 
		var ret,str = GetHashParamByString(this.handle, 0x2/*_HP_HASHVAL*/, size, size, 0);
		 
		if (ret) {
			return str;
		}
	};
	getHexValue = function( upper=true  ){
		var s = this.getValue(); 
		if( s ){
			var f = upper?"%02X":"%02x"
			var s = ..string.replace(s,".",
				function(c){
					return ..string.format(f, c[1] )
				}
			);  
			return s;
		}
	};
	hashData = function (data) {
		return HashData(this.handle , data, #data, 0);
	};
	deriveKey = function(algId = 0x6801/*_CALG_RC4*/, flag=0x00800000){
		var ret,hKey = DeriveKey(this.cryptContent.hCryptProv,algId,this.handle,flag); 
		if(ret){ 
			this.cryptContent.setKey(hKey);  
		};
	};
	destroy = function () {
		if (this.handle) {
			DestroyHash(this.handle); 
			if( this.cryptContent.lastHash == this){
				this.cryptContent.lastHash = null;
			}
			this.handle = null;
		};
	};
	@_meta;
}

namespace hash{
	//::Advapi32 := ..raw.loadDll("advapi32.dll");
	CreateHash = ::Advapi32.api("CryptCreateHash", "int(POINTER hProv,int algid,int hKey,int flags, pointer& phHash)");
	DestroyHash = ::Advapi32.api("CryptDestroyHash", "int(POINTER hHash)");
	HashData = ::Advapi32.api("CryptHashData", "bool(POINTER hHash, string pbData, int dwDataLen,INT flags)");
	GetHashParamByInt = ::Advapi32.api("CryptGetHashParam", "int(POINTER hHash, int type, int& pbBuff, int& pbBuffLen,int flags)");
	GetHashParamByString = ::Advapi32.api("CryptGetHashParam", "int(POINTER hHash, int type, string& pbBuff, int& pbBuffLen, int dwFlags)");		
	DeriveKey = ::Advapi32.api("CryptDeriveKey", "bool(POINTER hProv,INT Algid,POINTER hBaseData,int flags,pointer &phKey)");
}

/**intellisense()
crypt.hash() = !crypt_hash.
!crypt_hash.destroy() = 删除哈希对象
!crypt_hash.getValue() = 返回原始哈希值数据,\n即未转换为16进制
!crypt_hash.getHexValue() = 返回十六进制哈希值(大写)
!crypt_hash.getHexValue(false) = 返回十六进制哈希值(小写)
!crypt_hash.hashData(__/*字符串*/) = 计算哈希值
!crypt_hash.deriveKey() = 创建密钥,\n密钥自动绑定到CSP密钥容器对象\n该函数无返回值
end intellisense**/

