比赛名称:兰州大学第一届“飞马杯”程序设计竞赛(同步赛)
比赛时间:2021 年 05 月 29 日,12:00 - 17:00(5 小时)
比赛规则:ACM (个人赛)
主办:兰州大学 ICPC 程序设计集训队、兰州大学算法与程序设计协会
指导教师:马俊、程建军、燕昊、火克华
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void SHA_256(unsigned char*, const unsigned char*, size_t);
int main()
{
const char* awarded = "LZU-FeiMa: { ★★ }";
unsigned char hash[0x20];
SHA_256(hash, (unsigned char*)awarded, strlen(awarded));
printf("0x");
for (size_t i = 0; i != 0x20; ++i) {
printf("%02X", hash[i]);
}
return 0;
}
#define ROTATE_RIGHT(value, distance) (((value) >> (distance)) | ((value) << (0x20 - (distance))))
unsigned int bigEndianConversion(unsigned int originalValue, size_t length) {
if (!length) {
return originalValue & 0xFF;
}
return ((originalValue & 0xFF) << (length * 0x08)) | bigEndianConversion(originalValue >> 0x08, length - 0x01);
}
#define BIG_ENDIAN_CONVERSION(originalValue) (bigEndianConversion((originalValue), sizeof(unsigned int) - 0x01))
const unsigned int initializationVector[] = {
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
};
const unsigned int roundConstants[] = {
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
};
void SHA_256(unsigned char* result, const unsigned char* text, size_t length) {
unsigned char block[0x40];
size_t round, i;
unsigned int vector[0x08], word[0x40], j, k;
memcpy(result, initializationVector, 0x20);
for (round = 0; round <= (length + 0x08) / 0x40; ++round) {
if (round * 0x40 <= length) {
memcpy(block, text + round * 0x40, (round * 0x40 + 0x40 <= length ? 0x40 : length - round * 0x40));
}
if (round * 0x40 + 0x40 > length) {
if (round * 0x40 <= length) {
block[length - round * 0x40] = 0x80;
memset(block + length - round * 0x40 + 0x01, 0x00, round * 0x40 + 0x3F - length);
}
else {
memset(block, 0x00, 0x38);
}
if (round == (length + 0x08) / 0x40) {
for (i = 0; i != 0x08; ++i) {
block[i + 0x38] = (((unsigned long long)length * 0x08) >> (0x38 - i * 0x08)) & 0xFF;
}
}
}
for (i = 0; i != 0x10; ++i) {
word[i] = BIG_ENDIAN_CONVERSION(*(unsigned int*)(block + i * 0x04));
}
for (; i != 0x40; ++i) {
word[i] = word[i - 0x10] + word[i - 0x07];
word[i] += (word[i - 0x0F] >> 0x03) ^ ROTATE_RIGHT(word[i - 0x0F], 0x07) ^ ROTATE_RIGHT(word[i - 0x0F], 0x12);
word[i] += (word[i - 0x02] >> 0x0A) ^ ROTATE_RIGHT(word[i - 0x02], 0x11) ^ ROTATE_RIGHT(word[i - 0x02], 0x13);
}
memcpy(vector, result, 0x20);
for (i = 0; i != 0x40; ++i) {
j = ROTATE_RIGHT(vector[0x00], 0x02) ^ ROTATE_RIGHT(vector[0x00], 0x0D) ^ ROTATE_RIGHT(vector[0x00], 0x16);
j += (vector[0x00] & vector[0x01]) ^ (vector[0x00] & vector[0x02]) ^ (vector[0x01] & vector[0x02]);
k = vector[0x07] + word[i] + roundConstants[i];
k += ROTATE_RIGHT(vector[0x04], 0x06) ^ ROTATE_RIGHT(vector[0x04], 0x0B) ^ ROTATE_RIGHT(vector[0x04], 0x19);
k += (vector[0x04] & vector[0x05]) ^ (~vector[0x04] & vector[0x06]);
j += k;
k += vector[0x03];
memmove(vector + 0x01, vector, 0x1C);
vector[0x00] = j;
vector[0x04] = k;
}
for (i = 0; i != 0x08; ++i) {
*(unsigned int*)(result + i * 0x04) += vector[i];
}
}
for (i = 0; i != 0x08; ++i) {
*(unsigned int*)(result + i * 0x04) = BIG_ENDIAN_CONVERSION(*(unsigned int*)(result + i * 0x04));
}
}