相关文章:

  • SHA512系列哈希算法原理及实现(附源码)
  • SHA224和SHA256哈希算法原理及实现(附源码)
  • 国密SM3哈希算法原理及实现(附源码)
  • SHA1哈希算法原理及实现(附源码)
  • MD5哈希算法原理及实现(附源码)
  • MD4哈希算法原理及实现(附源码)
  • MD2哈希算法原理及实现(附源码)
  • MD2中用于随机置换的S盒是如何生成的?

最近陆续造了一批哈希算法的轮子,包括MD家族(包括MD2/MD4/MD5), SHA1, SHA2家族(SHA224, SHA256, SHA384, SHA512),SHA3家族以及国密SM3算法。

原来打算将每一个算法都详细分析并实现,现在看来,这个工作短时间可能无法完成,所以先将源码发上来。

这部分实现的源码完全参考官方文档的算法描述,连变量名也尽可能和官方文档中的变量保持一致,方便学习。

本篇主要是描述SHA512系列哈希算法的原理及实现,SHA512系列的哈希函数都是基于SHA512哈希函数扩展而来,这些列主要包括:

  • SHA512
  • SHA384 (初始化常量和SHA512不一样,结果哈希从512比特截断为384比特)
  • SHA512/224 (初始化常量和SHA512不一样,哈希结果从512比特截断为224比特,兼容SHA224)
  • SHA512/256 (初始化常量和SHA512不一样,哈希结果从512比特截断为256比特,兼容SHA256)
  • SHA512/t (t值不同,计算得到的初始化常量不同,哈希结果从512比特截断为t比特)

变长版本的SHA512t中:

  • 如果t=224,其结果和SHA512/224一样;
  • 如果t=256,其结果和SHA512/256一样;
  • FIPS 180-4中指出,没有t=384的变长版本

另外, SHA512系列函数的API封装调用接口参考了openssl官方的接口,完全兼容,无缝对接。会使用这里的接口,就会使用openssl的库函数接口,甚至连代码都不需要修改。

除了实现的源码外,还另外附带了一个测试例子,这个测试例子不仅仅是用于测试哈希算法的实现是否正确,还可以提供了"-f"/"-s"等选项用于对任意文件和字符串进行哈希,因此作为一个工具使用,类似系统内置的md5sum/sha1sum。

SHA512的实现源码

1. 头文件sha512.c

/** @        file: sha512.h* @ description: header file for sha512.c* @      author: Gu Yongqiang* @        blog: https://blog.csdn.net/guyongqiangx*/
#ifndef __ROCKY_SHA512__H
#define __ROCKY_SHA512__H#define ERR_OK           0
#define ERR_ERR         -1  /* generic error */
#define ERR_INV_PARAM   -2  /* invalid parameter */
#define ERR_TOO_LONG    -3  /* too long */
#define ERR_STATE_ERR   -4  /* state error */typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;
typedef unsigned int       uint32_t;
typedef unsigned long long uint64_t;
typedef struct {uint64_t high; /* high 64 bits */uint64_t low;  /*  low 64 bits */
} uint128_t;typedef struct sha512_context {/* message total length in bytes */uint128_t total;/* intermedia hash value for each block */struct {uint64_t a;uint64_t b;uint64_t c;uint64_t d;uint64_t e;uint64_t f;uint64_t g;uint64_t h;}hash;/* last block */struct {uint32_t used;      /* used bytes */uint8_t  buf[128];  /* block data buffer */}last;uint32_t ext;           /* t value of SHA512/t */
}SHA512_CTX;/* https://www.openssl.org/docs/man1.1.1/man3/SHA256_Final.html */
int SHA384_Init(SHA512_CTX *c);
int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA384_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md);int SHA512_Init(SHA512_CTX *c);
int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA512_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md);/* SHA512/224 */
int SHA512_224_Init(SHA512_CTX *c);
int SHA512_224_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA512_224_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA512_224(const unsigned char *d, size_t n, unsigned char *md);/* SHA512/256 */
int SHA512_256_Init(SHA512_CTX *c);
int SHA512_256_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA512_256_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA512_256(const unsigned char *d, size_t n, unsigned char *md);int SHA512t_Init(SHA512_CTX *c, unsigned int t);
int SHA512t_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA512t_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA512t(const unsigned char *d, size_t n, unsigned char *md, unsigned int t);#endif

2. 代码文件sha512.c

/** @        file: sha512.c* @ description: implementation for the SHA512, SHA384, SHA512/224, SHA512/256, SHA512/t Secure Hash Algorithm* @      author: Gu Yongqiang* @        blog: https://blog.csdn.net/guyongqiangx*/
#include <stdio.h>
#include <string.h>#include "utils.h"
#include "sha512.h"// #define DEBUG#ifdef DEBUG
#define DBG(...) printf(__VA_ARGS__)
#define DUMP_BLOCK_DATA 1
#define DUMP_BLOCK_HASH 1
#define DUMP_ROUND_DATA 0
#else
#define DBG(...)
#define DUMP_BLOCK_DATA 0
#define DUMP_BLOCK_HASH 0
#define DUMP_ROUND_DATA 0
#endif#define SHA512_BLOCK_SIZE           128 /* 1024 bits = 128 bytes */
#define SHA512_LEN_SIZE             16  /*  128 bits =  16 bytes */
#define SHA512_LEN_OFFSET           (SHA512_BLOCK_SIZE - SHA512_LEN_SIZE)
#define SHA512_DIGEST_SIZE          64  /*  512 bits =  64 bytes */#define SHA512_PADDING_PATTERN      0x80
#define SHA512_ROUND_NUM            80#define SHA384_DIGEST_SIZE          48  /*  384 bits =  48 bytes */
#define SHA512_224_DIGEST_SIZE      28  /*  224 bits =  28 bytes */
#define SHA512_256_DIGEST_SIZE      32  /*  256 bits =  32 bytes */#define HASH_BLOCK_SIZE             SHA512_BLOCK_SIZE
#define HASH_LEN_SIZE               SHA512_LEN_SIZE
#define HASH_LEN_OFFSET             SHA512_LEN_OFFSET#define HASH_DIGEST_SIZE            SHA512_DIGEST_SIZE#define HASH_PADDING_PATTERN        SHA512_PADDING_PATTERN
#define HASH_ROUND_NUM              SHA512_ROUND_NUM/* SHA512 Constants */
static const uint64_t K512[HASH_ROUND_NUM] =
{0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
};/* ROTate Right (cirular right shift) */
static uint64_t ROTR(uint64_t x, uint8_t shift)
{return (x >> shift) | (x << (64 - shift));
}/* Right SHift */
static uint64_t SHR(uint64_t x, uint8_t shift)
{return (x >> shift);
}/* Ch ... choose */
static uint64_t Ch(uint64_t x, uint64_t y, uint64_t z)
{return (x & y) ^ (~x & z) ;
}/* Maj ... majority */
static uint64_t Maj(uint64_t x, uint64_t y, uint64_t z)
{return (x & y) ^ (x & z) ^ (y & z);
}/* SIGMA0 */
static uint64_t SIGMA0(uint64_t x)
{return ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39);
}/* SIGMA1 */
static uint64_t SIGMA1(uint64_t x)
{return ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41);
}/* sigma0, different from SIGMA0 */
static uint64_t sigma0(uint64_t x)
{return ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7);
}/* sigma1, different from SIGMA1 */
static uint64_t sigma1(uint64_t x)
{return ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6);
}int SHA512_Init(SHA512_CTX *c)
{if (NULL == c){return ERR_INV_PARAM;}memset(c, 0, sizeof(SHA512_CTX));/* Initial Value for SHA512 */c->hash.a = 0x6a09e667f3bcc908;c->hash.b = 0xbb67ae8584caa73b;c->hash.c = 0x3c6ef372fe94f82b;c->hash.d = 0xa54ff53a5f1d36f1;c->hash.e = 0x510e527fade682d1;c->hash.f = 0x9b05688c2b3e6c1f;c->hash.g = 0x1f83d9abfb41bd6b;c->hash.h = 0x5be0cd19137e2179;c->total.low = 0;c->total.high = 0;c->last.used = 0;return ERR_OK;
}static int SHA512_PrepareScheduleWord(const uint64_t *block, uint64_t *W)
{uint32_t t;if ((NULL == block) || (NULL == W)){return ERR_INV_PARAM;}for (t=0; t<HASH_ROUND_NUM; t++){if (t<=15)  /*  0 <= t <= 15 */W[t] = be64toh(block[t]);else        /* 16 <= t <= 79 */W[t] = sigma1(W[t-2]) + W[t-7] + sigma0(W[t-15]) + W[t-16];}return ERR_OK;
}static int SHA512_UpdateTotal(uint128_t *x, uint64_t len)
{uint64_t l;l = (x->low + (((uint64_t)len)<<3)) & 0xffffffffffffffff;if (l < x->low)x->high++;//if (sizeof(len) >= 8)//  x->high += ((uint64_t)len)>> 61)x->low = l;return ERR_OK;
}#if 0
static int SHA512_SaveTotal(uint64_t *buffer, uint128_t *len)
{buffer[0] = htobe64(len->high);buffer[1] = htobe64(len->low);return ERR_OK;
}
#endif#if (DUMP_BLOCK_DATA == 1)
static int SHA512_GetBlockCount(SHA512_CTX *ctx, uint128_t * count)
{if (ctx->total.high == 0){count->low = ctx->total.low >> 10;count->high = 0;}else{count->low = ctx->total.low >> 10;count->low |= (ctx->total.high & 0x07FF << 54);count->high = ctx->total.high >> 10;}return ERR_OK;
}
#endifstatic int SHA512_ProcessBlock(SHA512_CTX *ctx, const void *block)
{uint32_t t;uint64_t W[HASH_ROUND_NUM];uint64_t T1, T2;uint64_t a, b, c, d, e, f, g, h;if ((NULL == ctx) || (NULL == block)){return ERR_INV_PARAM;}#if (DUMP_BLOCK_DATA == 1)DBG("---------------------------------------------------------\n");{uint128_t count;SHA512_GetBlockCount(ctx, &count);if (count.high == 0){DBG("   BLOCK: %llu\n", count.low);}else{DBG("   BLOCK: %llu%016llu\n", count.high, count.low);}}DBG("    DATA:\n");print_buffer(block, HASH_BLOCK_SIZE, "    ");
#endif/* prepare schedule word */SHA512_PrepareScheduleWord(block, W);a = ctx->hash.a;b = ctx->hash.b;c = ctx->hash.c;d = ctx->hash.d;e = ctx->hash.e;f = ctx->hash.f;g = ctx->hash.g;h = ctx->hash.h;#if (DUMP_BLOCK_HASH == 1)DBG("      IV: %016llx %016llx %016llx %016llx\n""          %016llx %016llx %016llx %016llx\n", \ctx->hash.a, ctx->hash.b, ctx->hash.c, ctx->hash.d, ctx->hash.e, ctx->hash.f, ctx->hash.g, ctx->hash.h);
#endiffor (t=0; t<HASH_ROUND_NUM; t++){T1 = h + SIGMA1(e) + Ch(e, f, g) + K512[t] + W[t];T2 = SIGMA0(a) + Maj(a, b, c);h = g;g = f;f = e;e = d + T1;d = c;c = b;b = a;a = T1 + T2;#if (DUMP_ROUND_DATA == 1)DBG("      %02d: T1=0x%016llx, T2=0x%016llx, W=0x%016llx\n", t, T1, T2, W[t]);DBG("           a=0x%016llx,  b=0x%016llx, c=0x%016llx, d=0x%016llx,\n""           e=0x%016llx,  f=0x%016llx, g=0x%016llx, h=0x%016llx\n",a, b, c, d, e, f, g, h);
#endif}ctx->hash.a += a;ctx->hash.b += b;ctx->hash.c += c;ctx->hash.d += d;ctx->hash.e += e;ctx->hash.f += f;ctx->hash.g += g;ctx->hash.h += h;#if (DUMP_BLOCK_HASH == 1)DBG("    HASH: %016llx %016llx %016llx %016llx\n""          %016llx %016llx %016llx %016llx\n",ctx->hash.a, ctx->hash.b, ctx->hash.c, ctx->hash.d, ctx->hash.e, ctx->hash.f, ctx->hash.g, ctx->hash.h);
#endifreturn ERR_OK;
}int SHA512_Update(SHA512_CTX *c, const void *data, size_t len)
{uint64_t copy_len = 0;if ((NULL == c) || (NULL == data)){return ERR_INV_PARAM;}/* has used data */if (c->last.used != 0){/* less than 1 block in total, combine data */if (c->last.used + len < HASH_BLOCK_SIZE){memcpy(&c->last.buf[c->last.used], data, len);c->last.used += len;return ERR_OK;}else /* more than 1 block */{/* process the block in context buffer */copy_len = HASH_BLOCK_SIZE - c->last.used;memcpy(&c->last.buf[c->last.used], data, copy_len);SHA512_ProcessBlock(c, &c->last.buf);SHA512_UpdateTotal(&c->total, HASH_BLOCK_SIZE);data = (uint8_t *)data + copy_len;len -= copy_len;/* reset context buffer */memset(&c->last.buf[0], 0, HASH_BLOCK_SIZE);c->last.used = 0;}}/* less than 1 block, copy to context buffer */if (len < HASH_BLOCK_SIZE){memcpy(&c->last.buf[c->last.used], data, len);c->last.used += len;return ERR_OK;}else{/* process data blocks */while (len >= HASH_BLOCK_SIZE){SHA512_ProcessBlock(c, data);SHA512_UpdateTotal(&c->total, HASH_BLOCK_SIZE);data = (uint8_t *)data + HASH_BLOCK_SIZE;len -= HASH_BLOCK_SIZE;}/* copy rest data to context buffer */memcpy(&c->last.buf[0], data, len);c->last.used = len;}return ERR_OK;
}int SHA512_Final(unsigned char *md, SHA512_CTX *c)
{uint64_t *temp;if ((NULL == c) || (NULL == md)){return ERR_INV_PARAM;}/* Last block should be less thant HASH_BLOCK_SIZE - HASH_LEN_SIZE */if (c->last.used >= (HASH_BLOCK_SIZE - HASH_LEN_SIZE)){SHA512_UpdateTotal(&c->total, c->last.used);/* one more block */c->last.buf[c->last.used] = HASH_PADDING_PATTERN;c->last.used++;memset(&c->last.buf[c->last.used], 0, HASH_BLOCK_SIZE - c->last.used);SHA512_ProcessBlock(c, &c->last.buf);c->last.used = 0;memset(&c->last.buf[0], 0, HASH_BLOCK_SIZE - HASH_LEN_SIZE);// SHA512_SaveTotal(&c->last.buf[HASH_LEN_OFFSET], &c->total);temp = (uint64_t *)&(c->last.buf[HASH_LEN_OFFSET]);temp[0] = htobe64(c->total.high);temp[1] = htobe64(c->total.low);SHA512_ProcessBlock(c, &c->last.buf);}else /* 0 <= last.used < HASH_BLOCK_SIZE - HASH_LEN_SIZE */{SHA512_UpdateTotal(&c->total, c->last.used);/* one more block */c->last.buf[c->last.used] = HASH_PADDING_PATTERN;c->last.used++;/* padding 0s */memset(&c->last.buf[c->last.used], 0, HASH_BLOCK_SIZE - HASH_LEN_SIZE - c->last.used);// SHA512_SaveTotal(&c->last.buf[HASH_LEN_OFFSET], &c->total);temp = (uint64_t *)&(c->last.buf[HASH_LEN_OFFSET]);temp[0] = htobe64(c->total.high);temp[1] = htobe64(c->total.low);SHA512_ProcessBlock(c, &c->last.buf);}temp = (uint64_t *)md;temp[0] = htobe64(c->hash.a);temp[1] = htobe64(c->hash.b);temp[2] = htobe64(c->hash.c);temp[3] = htobe64(c->hash.d);temp[4] = htobe64(c->hash.e);temp[5] = htobe64(c->hash.f);temp[6] = htobe64(c->hash.g);temp[7] = htobe64(c->hash.h);return ERR_OK;
}unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md)
{SHA512_CTX c;if ((NULL == d) || (NULL == md)){return NULL;}SHA512_Init(&c);SHA512_Update(&c, d, n);SHA512_Final(md, &c);return md;
}static int SHA512_xxx_Final(unsigned char *md, unsigned int md_size, SHA512_CTX *c)
{int rc = ERR_OK;unsigned char sha512_md[SHA512_DIGEST_SIZE];memset(&sha512_md, 0, sizeof(sha512_md));rc = SHA512_Final(sha512_md, c);memcpy(md, sha512_md, md_size);return rc;
}int SHA384_Init(SHA512_CTX *c)
{if (NULL == c){return ERR_INV_PARAM;}memset(c, 0, sizeof(SHA512_CTX));/* Initial Value for SHA384 */c->hash.a = 0xcbbb9d5dc1059ed8;c->hash.b = 0x629a292a367cd507;c->hash.c = 0x9159015a3070dd17;c->hash.d = 0x152fecd8f70e5939;c->hash.e = 0x67332667ffc00b31;c->hash.f = 0x8eb44a8768581511;c->hash.g = 0xdb0c2e0d64f98fa7;c->hash.h = 0x47b5481dbefa4fa4;c->total.low = 0;c->total.high = 0;c->last.used = 0;return ERR_OK;
}int SHA384_Update(SHA512_CTX *c, const void *data, size_t len)
{return SHA512_Update(c, data, len);
}int SHA384_Final(unsigned char *md, SHA512_CTX *c)
{return SHA512_xxx_Final(md, SHA384_DIGEST_SIZE, c);
}unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md)
{SHA512_CTX c;if ((NULL == d) || (NULL == md)){return NULL;}SHA384_Init(&c);SHA384_Update(&c, d, n);SHA384_Final(md, &c);return md;
}int SHA512_224_Init(SHA512_CTX *c)
{if (NULL == c){return ERR_INV_PARAM;}memset(c, 0, sizeof(SHA512_CTX));/* Initial Value for SHA512/224 */c->hash.a = 0x8c3d37c819544da2;c->hash.b = 0x73e1996689dcd4d6;c->hash.c = 0x1dfab7ae32ff9c82;c->hash.d = 0x679dd514582f9fcf;c->hash.e = 0x0f6d2b697bd44da8;c->hash.f = 0x77e36f7304c48942;c->hash.g = 0x3f9d85a86a1d36c8;c->hash.h = 0x1112e6ad91d692a1;c->total.low = 0;c->total.high = 0;c->last.used = 0;return ERR_OK;
}int SHA512_224_Update(SHA512_CTX *c, const void *data, size_t len)
{return SHA512_Update(c, data, len);
}int SHA512_224_Final(unsigned char *md, SHA512_CTX *c)
{return SHA512_xxx_Final(md, SHA512_224_DIGEST_SIZE, c);
}unsigned char *SHA512_224(const unsigned char *d, size_t n, unsigned char *md)
{SHA512_CTX c;if ((NULL == d) || (NULL == md)){return NULL;}SHA512_224_Init(&c);SHA512_224_Update(&c, d, n);SHA512_224_Final(md, &c);return md;
}int SHA512_256_Init(SHA512_CTX *c)
{if (NULL == c){return ERR_INV_PARAM;}memset(c, 0, sizeof(SHA512_CTX));/* Initial Value for SHA512/256 */c->hash.a = 0x22312194fc2bf72c;c->hash.b = 0x9f555fa3c84c64c2;c->hash.c = 0x2393b86b6f53b151;c->hash.d = 0x963877195940eabd;c->hash.e = 0x96283ee2a88effe3;c->hash.f = 0xbe5e1e2553863992;c->hash.g = 0x2b0199fc2c85b8aa;c->hash.h = 0x0eb72ddc81c52ca2;c->total.low = 0;c->total.high = 0;c->last.used = 0;return ERR_OK;
}int SHA512_256_Update(SHA512_CTX *c, const void *data, size_t len)
{return SHA512_Update(c, data, len);
}int SHA512_256_Final(unsigned char *md, SHA512_CTX *c)
{return SHA512_xxx_Final(md, SHA512_256_DIGEST_SIZE, c);
}unsigned char *SHA512_256(const unsigned char *d, size_t n, unsigned char *md)
{SHA512_CTX c;if ((NULL == d) || (NULL == md)){return NULL;}SHA512_256_Init(&c);SHA512_256_Update(&c, d, n);SHA512_256_Final(md, &c);return md;
}static int SHA512t_GenerateIV(SHA512_CTX *c, unsigned int t)
{char name[12]; /* 12 chars for "SHA-512/xxx", like "SHA512/224" */unsigned char md[SHA512_DIGEST_SIZE];SHA512_Init(c);c->hash.a ^= 0xa5a5a5a5a5a5a5a5;c->hash.b ^= 0xa5a5a5a5a5a5a5a5;c->hash.c ^= 0xa5a5a5a5a5a5a5a5;c->hash.d ^= 0xa5a5a5a5a5a5a5a5;c->hash.e ^= 0xa5a5a5a5a5a5a5a5;c->hash.f ^= 0xa5a5a5a5a5a5a5a5;c->hash.g ^= 0xa5a5a5a5a5a5a5a5;c->hash.h ^= 0xa5a5a5a5a5a5a5a5;/* "SHA-512/xxx" */memset(name, 0, sizeof(name));sprintf(name, "SHA-512/%d", t);SHA512_Update(c, name, strlen(name));SHA512_Final(md, c);#if (DUMP_BLOCK_HASH == 1)DBG("      IV: (%s)\n", name);DBG("          %016llx %016llx %016llx %016llx\n""          %016llx %016llx %016llx %016llx\n", \c->hash.a, c->hash.b, c->hash.c, c->hash.d, c->hash.e, c->hash.f, c->hash.g, c->hash.h);
#endifc->ext = t;return ERR_OK;
}int SHA512t_Init(SHA512_CTX *c, unsigned int t)
{if (NULL == c){return ERR_INV_PARAM;}/* t=8x, t!=0, t!=384, t!=512 */if (( t >= 512) || (0 != t%8) || (384 == t) || (0 == t)){return ERR_INV_PARAM;}memset(c, 0, sizeof(SHA512_CTX));/* Generate Initial Value for SHA512/t */SHA512t_GenerateIV(c, t);c->total.low = 0;c->total.high = 0;c->last.used = 0;return ERR_OK;
}int SHA512t_Update(SHA512_CTX *c, const void *data, size_t len)
{return SHA512_Update(c, data, len);
}int SHA512t_Final(unsigned char *md, SHA512_CTX *c)
{return SHA512_xxx_Final(md, c->ext/8, c);
}unsigned char *SHA512t(const unsigned char *d, size_t n, unsigned char *md, unsigned int t)
{SHA512_CTX c;if ((NULL == d) || (NULL == md)){return NULL;}if ((t > 512) || (t%8 != 0) || (t == 0) || (t == 384)){return NULL;}SHA512t_Init(&c, t);SHA512t_Update(&c, d, n);SHA512t_Final(md, &c);return md;
}

从上面的实现来看,SHA-384, SHA-512/224, SHA-512/256, SHA-512/t和SHA512的主要区别在于:

  • SHA-384, SHA-512/224, SHA-512/256, SHA-512/t初始化函数中的初始化常量不一致;
  • SHA-384, SHA-512/224, SHA-512/256, SHA-512/t哈希结果中,从基于SHA512得到的哈希中截取前面部分作为这几个函数的哈希值
  • SHA-512/t的初始化常量是通过t值计算的,不同的t值,计算得到的初始化常量不一样

SHA512源码的编译和测试

我直接在Makefile中内置了一个test伪目标,编译时除了编译生成名为sha512的哈希工具外,还会直接调用内置的哈希测试。

编译和运行如下:

$ make
gcc -Wall -g -O2 -c utils.c -o utils.o
gcc -Wall -g -O2 -c sha512.c -o sha512.o
gcc -Wall -g -O2 -c sha512test.c -o sha512test.o
gcc -Wall -g -O2 utils.o sha512.o sha512test.o -o sha512Run Test...
./sha512 -a sha384 -x
Internal hash tests for ./sha512(SHA384):
./sha512("")Expect: 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95bResult: 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b./sha512("a")Expect: 54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31Result: 54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31./sha512("abc")Expect: cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7Result: cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7./sha512("message digest")Expect: 473ed35167ec1f5d8e550368a3db39be54639f828868e9454c239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5Result: 473ed35167ec1f5d8e550368a3db39be54639f828868e9454c239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5./sha512("abcdefghijklmnopqrstuvwxyz")Expect: feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4Result: feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4./sha512("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")Expect: 1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84Result: 1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84./sha512("12345678901234567890123456789012345678901234567890123456789012345678901234567890")Expect: b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026Result: b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026./sha512 -a sha512 -x
Internal hash tests for ./sha512(SHA512):
./sha512("")Expect: cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3eResult: cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e./sha512("a")Expect: 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75Result: 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75./sha512("abc")Expect: ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49fResult: ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f./sha512("message digest")Expect: 107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7cResult: 107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c./sha512("abcdefghijklmnopqrstuvwxyz")Expect: 4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1Result: 4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1./sha512("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")Expect: 1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894Result: 1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894./sha512("12345678901234567890123456789012345678901234567890123456789012345678901234567890")Expect: 72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843Result: 72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843./sha512 -a sha512-224 -x
Internal hash tests for ./sha512(SHA512/224):
./sha512("")Expect: 6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4Result: 6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4./sha512("a")Expect: d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327Result: d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327./sha512("abc")Expect: 4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aaResult: 4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa./sha512("message digest")Expect: ad1a4db188fe57064f4f24609d2a83cd0afb9b398eb2fcaeaae2c564Result: ad1a4db188fe57064f4f24609d2a83cd0afb9b398eb2fcaeaae2c564./sha512("abcdefghijklmnopqrstuvwxyz")Expect: ff83148aa07ec30655c1b40aff86141c0215fe2a54f767d3f38743d8Result: ff83148aa07ec30655c1b40aff86141c0215fe2a54f767d3f38743d8./sha512("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")Expect: a8b4b9174b99ffc67d6f49be9981587b96441051e16e6dd036b140d3Result: a8b4b9174b99ffc67d6f49be9981587b96441051e16e6dd036b140d3./sha512("12345678901234567890123456789012345678901234567890123456789012345678901234567890")Expect: ae988faaa47e401a45f704d1272d99702458fea2ddc6582827556dd2Result: ae988faaa47e401a45f704d1272d99702458fea2ddc6582827556dd2./sha512 -a sha512-256 -x
Internal hash tests for ./sha512(SHA512/256):
./sha512("")Expect: c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967aResult: c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a./sha512("a")Expect: 455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8Result: 455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8./sha512("abc")Expect: 53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23Result: 53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23./sha512("message digest")Expect: 0cf471fd17ed69d990daf3433c89b16d63dec1bb9cb42a6094604ee5d7b4e9fbResult: 0cf471fd17ed69d990daf3433c89b16d63dec1bb9cb42a6094604ee5d7b4e9fb./sha512("abcdefghijklmnopqrstuvwxyz")Expect: fc3189443f9c268f626aea08a756abe7b726b05f701cb08222312ccfd6710a26Result: fc3189443f9c268f626aea08a756abe7b726b05f701cb08222312ccfd6710a26./sha512("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")Expect: cdf1cc0effe26ecc0c13758f7b4a48e000615df241284185c39eb05d355bb9c8Result: cdf1cc0effe26ecc0c13758f7b4a48e000615df241284185c39eb05d355bb9c8./sha512("12345678901234567890123456789012345678901234567890123456789012345678901234567890")Expect: 2c9fdbc0c90bdd87612ee8455474f9044850241dc105b1e8b94b8ddf5fac9148Result: 2c9fdbc0c90bdd87612ee8455474f9044850241dc105b1e8b94b8ddf5fac9148./sha512 -a sha512t -t 224 -x
Internal hash tests for ./sha512(SHA512/t):
./sha512("")Expect: 6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4Result: 6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4./sha512("a")Expect: d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327Result: d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327./sha512("abc")Expect: 4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aaResult: 4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa./sha512("message digest")Expect: ad1a4db188fe57064f4f24609d2a83cd0afb9b398eb2fcaeaae2c564Result: ad1a4db188fe57064f4f24609d2a83cd0afb9b398eb2fcaeaae2c564./sha512("abcdefghijklmnopqrstuvwxyz")Expect: ff83148aa07ec30655c1b40aff86141c0215fe2a54f767d3f38743d8Result: ff83148aa07ec30655c1b40aff86141c0215fe2a54f767d3f38743d8./sha512("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")Expect: a8b4b9174b99ffc67d6f49be9981587b96441051e16e6dd036b140d3Result: a8b4b9174b99ffc67d6f49be9981587b96441051e16e6dd036b140d3./sha512("12345678901234567890123456789012345678901234567890123456789012345678901234567890")Expect: ae988faaa47e401a45f704d1272d99702458fea2ddc6582827556dd2Result: ae988faaa47e401a45f704d1272d99702458fea2ddc6582827556dd2./sha512 -a sha384 -f sha512
./sha512(sha512) = 1b52191008c0e0094f0a9ab06227cdfed06863451013263c178c2a70839096a267ee7fc91de63893290a29e480835d28
./sha512 -a sha512 -f sha512
./sha512(sha512) = 3c451ef72cfbb060fb041bec35b0c5738b98ff01dace09794a8a095b5219036f88ad6e5bceba51a624c5889f65d3605a9920a07d4ce8e37b4d9d161e5bd94634
./sha512 -a sha512-224 -f sha512
./sha512(sha512) = 637747ac3951b51946bb80aab9be4951999a0e8a69c033567fc8d5ec
./sha512 -a sha512-256 -f sha512
./sha512(sha512) = 2265caf9c5ef1022ab306501269209561fab94e22efd32df20c3b74a6351547d
./sha512 -a sha512t -t 224 -f sha512
./sha512(sha512) = 637747ac3951b51946bb80aab9be4951999a0e8a69c033567fc8d5ec

最新版本的openssl工具已经支持SHA512系列的哈希算法(SHA-512/t除外),因此可以将sha512工具和openssl执行dgst计算的结果进行比较:

$ sha512 -h
Usage:
Common options: [-x|-f file|-s string| -a sha384|sha512|sha512-224|sha512-256|sha512t | -t num | -h]
Hash a string:sha512 -a sha384|sha512|sha512-224|sha512-256|sha512t -s string
Hash a file:sha512 -a sha384|sha512|sha512-224|sha512-256|sha512t -f file
-a      Secure hash algorithm: "sha384", "sha512", "sha512-224", "sha512-256"
-t      t value for SHA512/t, positive integer without a leading zero, (0<t<512, t/8=0, t!=384)
-x      Internal string hash test
-h      Display this message#
# 使用sha512工具分别对文件和字符串计算哈希值
#$ for h in sha384 sha512 sha512-224 sha512-256; \do \echo "sha512 -a $h -f sha512.o"; \sha512 -a $h -f sha512.o; \done;
sha512 -a sha384 -f sha512.o
sha512(sha512.o) = 46ebdfd95d7b5819d265ab9c1abe4e77409b59920cee91715e8e75728acc30c7f11e6f2680fedfaed13ddc78b3f9269a
sha512 -a sha512 -f sha512.o
sha512(sha512.o) = 815eab41765653993db44ebe013d496b0fd0d9649f8f88a3d859a507fbcc31f0c24de18514b513ff14bf6508e54f6527da49e627585dc6f8b81a97653020c310
sha512 -a sha512-224 -f sha512.o
sha512(sha512.o) = 999b0a92bd6a8559d3eb4921403c9d3132a1454ef3b1e60f37c17432
sha512 -a sha512-256 -f sha512.o
sha512(sha512.o) = 0e4f315c0af0e2e25e23bdf866338e65dc5885f9e90fa0484d1d1410f24a94b0$ S="I Love China!"; \for h in sha384 sha512 sha512-224 sha512-256; \do \echo "sha512 -a $h -s \"$S\""; \sha512 -a $h -s $S; \done;
sha512 -a sha384 -s "I Love China!"
sha512("I") = 54738b3c22eb17fa6f32dce8ae4c2bbf474ac7d89cf3aad01490246c943579ef28e6537f948eab03e5b8ecece20f0683
sha512 -a sha512 -s "I Love China!"
sha512("I") = 32b1786eca2b9f815b4c52b999e2b34dae877a86c00e8f745e7ac23388665c0703a947085bd7f975c5210ffab9b5a8f3931ab40b26cd7bccc4d7690cd19a4277
sha512 -a sha512-224 -s "I Love China!"
sha512("I") = 38f27409e58691cbd80c0c6258117446b53e75a9895827ddbd85f53a
sha512 -a sha512-256 -s "I Love China!"
sha512("I") = 7cdd023a2896a7c29338a40033fe9b711678861c5b43eaa36347ecc35d25d1c0#
# 使用开源的openssl工具计算相应的哈希进行对比
#
$ for h in sha384 sha512 sha512-224 sha512-256; \do \echo "openssl dgst -$h sha512.o"; \openssl dgst -$h sha512.o; \done;
openssl dgst -sha384 sha512.o
SHA384(sha512.o)= 46ebdfd95d7b5819d265ab9c1abe4e77409b59920cee91715e8e75728acc30c7f11e6f2680fedfaed13ddc78b3f9269a
openssl dgst -sha512 sha512.o
SHA512(sha512.o)= 815eab41765653993db44ebe013d496b0fd0d9649f8f88a3d859a507fbcc31f0c24de18514b513ff14bf6508e54f6527da49e627585dc6f8b81a97653020c310
openssl dgst -sha512-224 sha512.o
SHA512-224(sha512.o)= 999b0a92bd6a8559d3eb4921403c9d3132a1454ef3b1e60f37c17432
openssl dgst -sha512-256 sha512.o
SHA512-256(sha512.o)= 0e4f315c0af0e2e25e23bdf866338e65dc5885f9e90fa0484d1d1410f24a94b0$ S="I Love China!"; \for h in sha384 sha512 sha512-224 sha512-256; \do \echo "echo -n \"$S\" | openssl dgst -$h"; \echo -n \"$S\" | openssl dgst -$h; \done;
echo -n "I Love China!" | openssl dgst -sha384
(stdin)= 10e849acdc83e320de1d092a0a582e3af1055bd55150c7d81a88d52145241b686ac0a9ef713a6da8a9e73e5af33c2355
echo -n "I Love China!" | openssl dgst -sha512
(stdin)= fbd797a0ef6fd8cfdb9e5efffbc24eac2e60f4193440ee58a5608a2aff96dab1c22435e05fcc6e018a5a9e4e0827ef670f600e22da028ff2fd9c29d0843aa945
echo -n "I Love China!" | openssl dgst -sha512-224
(stdin)= ecd4de998d134d52ce6c379b9bd7dcd2d4405873b593cdb2ece3ab7c
echo -n "I Love China!" | openssl dgst -sha512-256
(stdin)= 159369bde3fb15b7d5e20a163e66e43601be5eff963b8c554dba114c54f78017

完整代码

完整的代码文件列表如下:

sha512$ ls -lh
total 60K
-rwxr-xr-x 1 rg935739 stb_all  942 Jun 22 17:20 Makefile
-rwxr-xr-x 1 rg935739 stb_all  18K Jun 22 18:21 sha512.c
-rwxr-xr-x 1 rg935739 stb_all 2.6K Jun 21 09:48 sha512.h
-rwxr-xr-x 1 rg935739 stb_all  22K Jun 22 18:06 sha512test.c
-rwxr-xr-x 1 rg935739 stb_all  758 Jun 21 09:48 utils.c
-rwxr-xr-x 1 rg935739 stb_all 1.8K Jun 21 09:48 utils.h

需要代码请访问:

  • https://github.com/guyongqiangx/cryptography/

其它

洛奇工作中常常会遇到自己不熟悉的问题,这些问题可能并不难,但因为不了解,找不到人帮忙而瞎折腾,往往导致浪费几天甚至更久的时间。

所以我组建了几个微信讨论群(记得微信我说加哪个群,如何加微信见后面),欢迎一起讨论:

  • 一个密码编码学讨论组,主要讨论各种加解密,签名校验等算法,请说明加密码学讨论群。
  • 一个Android OTA的讨论组,请说明加Android OTA群。
  • 一个git和repo的讨论组,请说明加git和repo群。

在工作之余,洛奇尽量写一些对大家有用的东西,如果洛奇的这篇文章让您有所收获,解决了您一直以来未能解决的问题,不妨赞赏一下洛奇,这也是对洛奇付出的最大鼓励。扫下面的二维码赞赏洛奇,金额随意:

洛奇自己维护了一个公众号“洛奇看世界”,一个很佛系的公众号,不定期瞎逼逼。公号也提供个人联系方式,一些资源,说不定会有意外的收获,详细内容见公号提示。扫下方二维码关注公众号:

SHA512系列哈希算法原理及实现(附源码)相关推荐

  1. SHA3系列(KECCAK)哈希算法原理及实现(附源码)

    相关文章: (本文持续更新中) SHA3系列(KECCAK)哈希算法原理及实现(附源码) SHA512系列哈希算法原理及实现(附源码) SHA224和SHA256哈希算法原理及实现(附源码) 国密SM ...

  2. SHA224和SHA256哈希算法原理及实现(附源码)

    相关文章: SHA224和SHA256哈希算法原理及实现(附源码) 国密SM3哈希算法原理及实现(附源码) SHA1哈希算法原理及实现(附源码) MD5哈希算法原理及实现(附源码) MD4哈希算法原理 ...

  3. 国密SM3密码杂凑算法原理及实现(附源码)

    相关文章: 国密SM3哈希算法原理及实现(附源码) SHA1哈希算法原理及实现(附源码) MD5哈希算法原理及实现(附源码) MD4哈希算法原理及实现(附源码) MD2哈希算法原理及实现(附源码) M ...

  4. android 原生开发 3d地图 下载_arcgis api 3.x for js 入门开发系列二不同地图服务展示(附源码下载)...

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  5. linux直流电机测试,带霍尔传感器编码器的直流减速电机测速原理讲解(附源码)...

    查看: 14294|回复: 83 带霍尔传感器编码器的直流减速电机测速原理讲解(附源码) 高级会员, 积分 891, 距离下一级还需 109 积分 积分金钱891 注册时间2019-4-22 在线时间 ...

  6. 超详讲解图像拼接/全景图原理和应用 | 附源码

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 概述 图像拼接是计算机视觉中最成功的应用之一.如今,很难找到不包含 ...

  7. python全景图像拼接_超详讲解图像拼接/全景图原理和应用 | 附源码

    研究好玩又有用的技术第 008 期 在学习中发现快乐,在应用找到价值.这是我第八期分享图像技术应用的文章. 前七期欢迎阅读和分享: 概述 作者:Thalles Silva 编译:AI算法与图像处理 图 ...

  8. 基于Vision Transformer的图像去雾算法研究与实现(附源码)

    基于Vision Transformer的图像去雾算法研究与实现 0. 服务器性能简单监控 \LOG_USE_CPU_MEMORY\文件夹下的use_memory.py文件可以实时输出CPU使用率以及 ...

  9. 人工智能 - A*算法解决迷宫问题 附源码和可视化显示

    写在最前,先附上可视化后的效果: 一.问题描述 迷宫问题可以表述为:一个二维的网格,0 表示点可走,1 表示点 不可以走,点用(x,y)表示,寻找从某一个给定的起始单元格出发, 经由行相邻或列相邻的单 ...

最新文章

  1. win10系统的qq无网络连接网络连接到服务器,Win10系统下误报无法连接internet该怎么办?新手速看...
  2. 小白的python之路11/3总结
  3. Oracle系统结构之修改oracle内存参数
  4. python恶搞小程序-有趣的python小程序
  5. 漂亮的NavMenu导航控件
  6. 【机器学习基础】xgboost系列丨xgboost建树过程分析及代码实现
  7. c++静态成员变量使用前必须初始化,那么下面这个例子为什么不用初始化?
  8. SM30 - SMOFOBJECT
  9. C++ char[] 与 string 转换
  10. Java IO: 其他字节流(上)
  11. SpringBoot2.0基础案例(01):环境搭建和RestFul风格接口
  12. c语言组json包,json格式解析和libjson的用法介绍(关于cjson的使用方法)
  13. 我竟然用git send-mail通过QQ邮箱提交了push request
  14. ios 去掉cell最后一条分割线
  15. C#图像处理教程:VS2022+Win7+OpenCvSharp4创建第一个图像处理实例hello lenna
  16. IMX6ULL开发板,系统移植——第一步Uboot移植
  17. Java实现抓取百度识图结果的实现和思路-1-创造百度识图的URL链接
  18. android图片尺寸大小设置
  19. 专利申请过程中的重要文件总结
  20. 网页的背景颜色变化效果

热门文章

  1. 碎嘴子教学mysql数据库自增
  2. ipone低版本页面不渲染问题
  3. 国家邮政局发布2021年快递服务满意度和时限准时率测结果
  4. Java基础项目:家庭记录收支程序
  5. 【内附源码和文档】在线课堂管理平台的设计与实现
  6. NRF52832学习笔记(27)——非易失性存储器控制器NVMC
  7. 细分赛道下,若羽臣小体量,大挑战
  8. SAR图像的干涉相位 matlab_时空双缝干涉
  9. 公司想申请软著投标加分,没有源代码也可以申请
  10. 商品评论获取与词云图可视化分析