瀏覽代碼

Merge pull request #5250 from bojidar-bg/add-sha256

Add sha256 to String and File/FileAccess.
Juan Linietsky 9 年之前
父節點
當前提交
ebbd705b63
共有 10 個文件被更改,包括 366 次插入7 次删除
  1. 7 0
      core/bind/core_bind.cpp
  2. 1 0
      core/bind/core_bind.h
  3. 5 0
      core/io/sha-README.md
  4. 245 0
      core/io/sha256.c
  5. 50 0
      core/io/sha256.h
  6. 33 0
      core/os/file_access.cpp
  7. 1 0
      core/os/file_access.h
  8. 20 7
      core/ustring.cpp
  9. 2 0
      core/ustring.h
  10. 2 0
      core/variant_call.cpp

+ 7 - 0
core/bind/core_bind.cpp

@@ -1558,6 +1558,12 @@ String _File::get_md5(const String& p_path) const {
 
 }
 
+String _File::get_sha256(const String& p_path) const {
+
+	return FileAccess::get_sha256(p_path);
+
+}
+
 
 String _File::get_line() const{
 
@@ -1748,6 +1754,7 @@ void _File::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("get_line"),&_File::get_line);
 	ObjectTypeDB::bind_method(_MD("get_as_text"),&_File::get_as_text);
 	ObjectTypeDB::bind_method(_MD("get_md5","path"),&_File::get_md5);
+	ObjectTypeDB::bind_method(_MD("get_sha256","path"),&_File::get_md5);
 	ObjectTypeDB::bind_method(_MD("get_endian_swap"),&_File::get_endian_swap);
 	ObjectTypeDB::bind_method(_MD("set_endian_swap","enable"),&_File::set_endian_swap);
 	ObjectTypeDB::bind_method(_MD("get_error:Error"),&_File::get_error);

+ 1 - 0
core/bind/core_bind.h

@@ -380,6 +380,7 @@ public:
 	String get_line() const;
 	String get_as_text() const;
 	String get_md5(const String& p_path) const;
+	String get_sha256(const String& p_path) const;
 
 	/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
 	 * It's not about the current CPU type but file formats.

+ 5 - 0
core/io/sha-README.md

@@ -0,0 +1,5 @@
+SHA256
+======
+
+SHA-256 implementation to compliment a portable byte-oriented AES-256 
+implementation in C at http://www.literatecode.com/aes256 

+ 245 - 0
core/io/sha256.c

@@ -0,0 +1,245 @@
+/*
+*   SHA-256 implementation.
+*
+*   Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com
+*
+*   Permission to use, copy, modify, and distribute this software for any
+*   purpose with or without fee is hereby granted, provided that the above
+*   copyright notice and this permission notice appear in all copies.
+*
+*   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+*   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+*   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+*   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+*   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+*   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+*   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+#define SWAP_BYTES
+// #define USE_STD_MEMCPY
+// #define SELF_TEST
+
+#ifdef USE_STD_MEMCPY
+#include <string.h>
+#endif
+#include "sha256.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RL(x,n)   (((x) << n) | ((x) >> (32 - n)))
+#define RR(x,n)   (((x) >> n) | ((x) << (32 - n)))
+
+#define S0(x)  (RR((x), 2) ^ RR((x),13) ^ RR((x),22))
+#define S1(x)  (RR((x), 6) ^ RR((x),11) ^ RR((x),25))
+#define G0(x)  (RR((x), 7) ^ RR((x),18) ^ ((x) >> 3))
+#define G1(x)  (RR((x),17) ^ RR((x),19) ^ ((x) >> 10))
+
+#ifdef SWAP_BYTES
+#define BSWP(x,y)  _bswapw((uint32_t *)(x), (uint32_t)(y))
+#else
+#define BSWP(p,n)
+#endif
+#ifdef USE_STD_MEMCPY
+#define MEMCP(x,y,z) memcpy((x),(y),(z))
+#else
+#define MEMCP(x,y,z) _memcp((x),(y),(z))
+#endif
+
+#ifndef __cdecl
+#define __cdecl
+#endif
+
+static const uint32_t K[64] = {
+     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+     0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+     0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+     0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+     0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+     0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+     0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+/* -------------------------------------------------------------------------- */
+static void _bswapw(uint32_t *p, uint32_t i)
+{
+    while (i--) p[i] = (RR(p[i],24) & 0x00ff00ff) | (RR(p[i],8) & 0xff00ff00);
+
+} /* _bswapw */
+
+/* -------------------------------------------------------------------------- */
+#ifndef USE_STD_MEMCPY
+void * __cdecl _memcp (void *d, const void *s, uint32_t sz)
+{
+    void *rv = d;
+
+    while (sz--) *(char *)d = *(char *)s, d = (char *)d + 1,  s = (char *)s + 1;
+
+    return(rv);
+} /* _memcp */
+#endif
+
+/* -------------------------------------------------------------------------- */
+static void _rtrf(uint32_t *b, uint32_t *p, uint32_t i, uint32_t j)
+{
+    #define B(x, y) b[(x-y) & 7]
+    #define P(x, y) p[(x+y) & 15]
+
+    B(7,i) += (j ? (p[i & 15] += G1(P(i,14)) + P(i,9) + G0(P(i,1))) : p[i & 15])
+              + K[i+j] + S1(B(4,i))
+              + (B(6,i) ^ (B(4,i) & (B(5,i) ^ B(6,i))));
+    B(3,i) += B(7,i);
+    B(7,i) += S0(B(0,i)) + ( (B(0,i) & B(1,i)) | (B(2,i) & (B(0,i) ^ B(1,i))) );
+
+    #undef P
+    #undef B
+} /* _rtrf */
+
+/* -------------------------------------------------------------------------- */
+static void _hash(sha256_context *ctx)
+{
+    uint32_t b[8], *p, j;
+
+    b[0] = ctx->hash[0]; b[1] = ctx->hash[1]; b[2] = ctx->hash[2];
+    b[3] = ctx->hash[3]; b[4] = ctx->hash[4]; b[5] = ctx->hash[5];
+    b[6] = ctx->hash[6]; b[7] = ctx->hash[7];
+
+    for (p = ctx->buf, j = 0; j < 64; j += 16)
+        _rtrf(b, p,  0, j), _rtrf(b, p,  1, j), _rtrf(b, p,  2, j),
+        _rtrf(b, p,  3, j), _rtrf(b, p,  4, j), _rtrf(b, p,  5, j),
+        _rtrf(b, p,  6, j), _rtrf(b, p,  7, j), _rtrf(b, p,  8, j),
+        _rtrf(b, p,  9, j), _rtrf(b, p, 10, j), _rtrf(b, p, 11, j),
+        _rtrf(b, p, 12, j), _rtrf(b, p, 13, j), _rtrf(b, p, 14, j),
+        _rtrf(b, p, 15, j);
+
+    ctx->hash[0] += b[0]; ctx->hash[1] += b[1]; ctx->hash[2] += b[2];
+    ctx->hash[3] += b[3]; ctx->hash[4] += b[4]; ctx->hash[5] += b[5];
+    ctx->hash[6] += b[6]; ctx->hash[7] += b[7];
+
+} /* _hash */
+
+/* -------------------------------------------------------------------------- */
+void sha256_init(sha256_context ctx[1])
+{
+    ctx->len[0] = ctx->len[1] = 0;
+    ctx->hash[0] = 0x6a09e667; ctx->hash[1] = 0xbb67ae85;
+    ctx->hash[2] = 0x3c6ef372; ctx->hash[3] = 0xa54ff53a;
+    ctx->hash[4] = 0x510e527f; ctx->hash[5] = 0x9b05688c;
+    ctx->hash[6] = 0x1f83d9ab; ctx->hash[7] = 0x5be0cd19;
+
+} /* sha256_init */
+
+/* -------------------------------------------------------------------------- */
+void sha256_hash(sha256_context *ctx, uint8_t *dat, uint32_t sz)
+{
+    register uint32_t i = ctx->len[0] & 63, l, j;
+
+    if ((ctx->len[0] += sz) < sz)  ++(ctx->len[1]);
+
+    for (j = 0, l = 64-i; sz >= l; j += l, sz -= l, l = 64, i = 0)
+    {
+        MEMCP(&ctx->buf[i], &dat[j], l);
+        BSWP(ctx->buf, 16 );
+        _hash(ctx);
+    }
+    MEMCP(&ctx->buf[i], &dat[j], sz);
+
+} /* _hash */
+
+/* -------------------------------------------------------------------------- */
+void sha256_done(sha256_context *ctx, uint8_t *buf)
+{
+    uint32_t i = (uint32_t)(ctx->len[0] & 63), j = ((~i) & 3) << 3;
+
+    BSWP(ctx->buf, (i + 3) >> 2);
+
+    ctx->buf[i >> 2] &= 0xffffff80 << j;  /* add padding */
+    ctx->buf[i >> 2] |= 0x00000080 << j;
+
+    if (i < 56) i = (i >> 2) + 1;
+       else ctx->buf[15] ^= (i < 60) ? ctx->buf[15] : 0, _hash(ctx), i = 0;
+
+    while (i < 14) ctx->buf[i++] = 0;
+
+    ctx->buf[14] = (ctx->len[1] << 3)|(ctx->len[0] >> 29); /* add length */
+    ctx->buf[15] = ctx->len[0] << 3;
+
+    _hash(ctx);
+
+    for (i = 0; i < 32; i++)
+       ctx->buf[i % 16] = 0, /* may remove this line in case of a DIY cleanup */
+       buf[i] = (uint8_t)(ctx->hash[i >> 2] >> ((~i & 3) << 3));
+
+} /* sha256_done */
+
+
+#ifdef SELF_TEST
+#pragma warning (push, 0)
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#pragma warning(pop)
+
+char *buf[] = {
+    "",
+    "e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855",
+
+    "abc",
+    "ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad",
+
+    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+    "248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1",
+
+    "The quick brown fox jumps over the lazy dog",
+    "d7a8fbb3 07d78094 69ca9abc b0082e4f 8d5651e4 6d3cdb76 2d02d0bf 37c9e592",
+
+    "The quick brown fox jumps over the lazy cog", /* avalanche effect test */
+    "e4c4d8f3 bf76b692 de791a17 3e053211 50f7a345 b46484fe 427f6acc 7ecc81be",
+
+    "bhn5bjmoniertqea40wro2upyflkydsibsk8ylkmgbvwi420t44cq034eou1szc1k0mk46oeb7ktzmlxqkbte2sy",
+    "9085df2f 02e0cc45 5928d0f5 1b27b4bf 1d9cd260 a66ed1fd a11b0a3f f5756d99"
+};
+
+int main(int argc, char *argv[])
+{
+    sha256_context ctx;
+    uint8_t hv[32];
+    uint32_t i, j;
+
+    for (j = 0; j < (sizeof(buf)/sizeof(buf[0])); j += 2)
+    {
+        sha256_init(&ctx);
+        sha256_hash(&ctx, (uint8_t *)buf[j], (uint32_t)strlen(buf[j]));
+        sha256_done(&ctx, hv);
+        printf("input = %s\ndigest: %s\nresult: ", buf[j], buf[j+1]);
+        for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":"");
+        printf("\n\n");
+    }
+
+    for (j = 1; j < (uint32_t)argc; j++)
+    {
+        printf("argv[%d]: %s\nresult: ", (int)j, argv[j]);
+        sha256_init(&ctx);
+        sha256_hash(&ctx, (uint8_t *)argv[j], (uint32_t)strlen(argv[j]));
+        sha256_done(&ctx, hv);
+        for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":"");
+        printf("\n\n");
+    }
+
+    return 0;
+} /* main */
+#endif
+
+#ifdef __cplusplus
+}
+#endif

+ 50 - 0
core/io/sha256.h

@@ -0,0 +1,50 @@
+/*
+*   SHA-256 implementation.
+*
+*   Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com
+*
+*   Permission to use, copy, modify, and distribute this software for any
+*   purpose with or without fee is hereby granted, provided that the above
+*   copyright notice and this permission notice appear in all copies.
+*
+*   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+*   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+*   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+*   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+*   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+*   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+*   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+#ifdef _MSC_VER
+#ifndef uint8_t
+typedef unsigned __int8 uint8_t;
+#endif
+#ifndef uint32_t
+typedef unsigned __int32 uint32_t;
+#endif
+#ifndef uint64_t
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#endif
+#else
+#include <stdint.h>
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+   typedef struct {
+       uint32_t buf[16];
+       uint32_t hash[8];
+       uint32_t len[2];
+   } sha256_context;
+
+   void sha256_init(sha256_context *);
+   void sha256_hash(sha256_context *, uint8_t * /* data */, uint32_t /* len */);
+   void sha256_done(sha256_context *, uint8_t * /* hash */);
+
+#ifdef __cplusplus
+}
+#endif

+ 33 - 0
core/os/file_access.cpp

@@ -31,6 +31,7 @@
 #include "os/os.h"
 #include "core/io/marshalls.h"
 #include "io/md5.h"
+#include "io/sha256.h"
 #include "core/io/file_access_pack.h"
 
 FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX]={0,0};
@@ -517,6 +518,38 @@ String FileAccess::get_md5(const String& p_file) {
 
 }
 
+String FileAccess::get_sha256(const String& p_file) {
+
+	FileAccess *f=FileAccess::open(p_file,READ);
+	if (!f)
+		return String();
+
+	sha256_context sha256;
+	sha256_init(&sha256);
+
+	unsigned char step[32768];
+
+	while(true) {
+
+		int br = f->get_buffer(step,32768);
+		if (br>0) {
+
+			sha256_hash(&sha256,step,br);
+		}
+		if (br < 4096)
+			break;
+
+	}
+
+	unsigned char hash[32];
+
+	sha256_done(&sha256, hash);
+
+	memdelete(f);
+	return String::hex_encode_buffer(hash, 32);
+
+}
+
 FileAccess::FileAccess() {
 
 	endian_swap=false;

+ 1 - 0
core/os/file_access.h

@@ -153,6 +153,7 @@ public:
 	static bool is_backup_save_enabled() { return backup_save; };
 
 	static String get_md5(const String& p_file);
+	static String get_sha256(const String& p_file);
 
 	static Vector<uint8_t> get_file_as_array(const String& p_path);
 

+ 20 - 7
core/ustring.cpp

@@ -32,6 +32,7 @@
 #include "print_string.h"
 #include "math_funcs.h"
 #include "io/md5.h"
+#include "io/sha256.h"
 #include "ucaps.h"
 #include "color.h"
 #include "variant.h"
@@ -849,21 +850,23 @@ const CharType * String::c_str() const {
 }
 
 String String::md5(const uint8_t *p_md5) {
+	return String::hex_encode_buffer(p_md5, 16);
+}
 
-	String ret;
+String String::hex_encode_buffer(const uint8_t *p_buffer, int p_len) {
+	static const char hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
 
-	for(int i=0;i<16;i++) {
+	String ret;
+	char v[2]={0,0};
 
-		static const char hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
-		char v[2]={0,0};
-		v[0]=hex[p_md5[i]>>4];
+	for(int i=0;i<p_len;i++) {
+		v[0]=hex[p_buffer[i]>>4];
 		ret+=v;
-		v[0]=hex[p_md5[i]&0xF];
+		v[0]=hex[p_buffer[i]&0xF];
 		ret+=v;
 	}
 
 	return ret;
-
 }
 
 String String::chr(CharType p_char) {
@@ -2389,6 +2392,16 @@ String String::md5_text() const {
 	return String::md5(ctx.digest);
 }
 
+String String::sha256_text() const {
+	CharString cs=utf8();
+	unsigned char hash[32];
+	sha256_context ctx;
+	sha256_init(&ctx);
+	sha256_hash(&ctx,(unsigned char*)cs.ptr(),cs.length());
+	sha256_done(&ctx, hash);
+	return String::hex_encode_buffer(hash, 32);
+}
+
 Vector<uint8_t> String::md5_buffer() const {
 
 	CharString cs=utf8();

+ 2 - 0
core/ustring.h

@@ -140,6 +140,7 @@ public:
 	static String num_int64(int64_t p_num,int base=10,bool capitalize_hex=false);
 	static String chr(CharType p_char);
 	static String md5(const uint8_t *p_md5);
+	static String hex_encode_buffer(const uint8_t *p_buffer, int p_len);
 	bool is_numeric() const;
 	double to_double() const;
 	float to_float() const;
@@ -193,6 +194,7 @@ public:
 	uint32_t hash() const; /* hash the string */
 	uint64_t hash64() const; /* hash the string */
 	String md5_text() const;
+	String sha256_text() const;
 	Vector<uint8_t> md5_buffer() const;
 
 	inline bool empty() const { return length() == 0; }

+ 2 - 0
core/variant_call.cpp

@@ -267,6 +267,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
 	VCALL_LOCALMEM2(String,erase);
 	VCALL_LOCALMEM0R(String,hash);
 	VCALL_LOCALMEM0R(String,md5_text);
+	VCALL_LOCALMEM0R(String,sha256_text);
 	VCALL_LOCALMEM0R(String,md5_buffer);
 	VCALL_LOCALMEM0R(String,empty);
 	VCALL_LOCALMEM0R(String,is_abs_path);
@@ -1294,6 +1295,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
 	ADDFUNC2(STRING,NIL,String,erase,INT,"pos",INT,"chars", varray());
 	ADDFUNC0(STRING,INT,String,hash,varray());
 	ADDFUNC0(STRING,STRING,String,md5_text,varray());
+	ADDFUNC0(STRING,STRING,String,sha256_text,varray());
 	ADDFUNC0(STRING,RAW_ARRAY,String,md5_buffer,varray());
 	ADDFUNC0(STRING,BOOL,String,empty,varray());
 	ADDFUNC0(STRING,BOOL,String,is_abs_path,varray());