比赛名称:兰州大学第一届“飞马杯”程序设计竞赛(同步赛)
比赛时间: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)); } }