SHA-1的数据填充与扩展实验-Python

这次来展示下,SHA-1中的数据填充与扩展的Python代码实现!!!

首先是将输入的数据进行转换,转换为二进制数,转化的过程如下:

输入的消息 -> 转化为相应的ASCII码 -> 再由ASCII转换为二进制

在SHA-1中,最后的64比特位是来表示数据的长度,所以SHA-1可以检测的长度为2的64次方减去1,这个数字还是很大的。以512比特为一组数据,剩下不足512比特的需要进行补足,并且在末尾的64比特来表示数据的长度。

1.数据转化

这里推荐使用format(news,'b')这个函数来转化,其中的'b'表示转换为二进制,'x'可以转化为十六进制,一是可以直接转化为相应的进制,二是可以省去前面的进制头部如0b,0x等,可以省去一些不必要的步骤,缩短代码。

#news = input("输入消息:")
news = "abc"
#############################################

asc = []
for i in news:#每个字符的ASCII码转二进制
    asc.append(format(ord(i),'b').zfill(8))
news_len = 8 * len(asc)#消息完整长度
lenth = (8 * len(asc)) % 512#消息长度
asc = "".join(asc)#消息
filling = "1" + (447 - lenth) * "0"#附加位元
supplyment = format(news_len,'b').zfill(64)#消息长度
whole = asc + filling + supplyment#完整512比特

#############################################

代码里lenth = (8 * len(asc) ) % 512用来判断数据的长度是否超过了完整的512比特,如果超过,就对超过的部分进行补足,这里的数据量小,就不进行多余操作了。

2.数据扩展

group = []
for i in range(0,len(whole),32):
    num = format(eval("0b"+whole[i:i+32]),'x').zfill(8)
    group.append("0x"+num)
def leftround_207206(num):#左移一位
    return num[1:] + num[0]
def data_expand_207206(group):#数据扩展
    t = len(group)
    initial = eval(group[t - 16]) ^ eval(group[t - 14]) ^ eval(group[t - 8]) ^ eval(group[t - 3])
    xor = leftround_207206(format(initial, 'b').zfill(32))
    result = "0x" + format(eval("0b" + xor), 'x').zfill(8)
    group.append(result)
    result = group
    return result
for i in range(16,80):#
    expand = data_expand_207206(group)
    group = expand
#############################################
from time import *
for i in range(len(group)):
    #sleep(1)
    print(f'W{i}:{group[i]}')

将数据以32比特位为一组输入进空列表group,数据扩展定义为一个函数实现,进行循环得到W16至W79.

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
SHA-1算法数据填充扩展c语言实现如下: ```c #include <stdio.h> #include <stdint.h> #include <string.h> #define SHA1_BLOCK_SIZE 64 // 定义 SHA-1 的结构体,用于存储状态 typedef struct { uint32_t state[5]; uint32_t count[2]; uint8_t buffer[SHA1_BLOCK_SIZE]; } SHA1_CTX; // 定义函数 ROTATE_LEFT,用于左移 n 位 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) // 定义函数 SHA1Transform,用于进行 SHA-1 的变换 static void SHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_SIZE]) { uint32_t a, b, c, d, e, temp; uint32_t w[80]; // 将输入的 64 字节数据分成 16 个 32 位的块 for (int i = 0; i < 16; i++) { w[i] = (buffer[i * 4] << 24) | (buffer[i * 4 + 1] << 16) | (buffer[i * 4 + 2] << 8) | buffer[i * 4 + 3]; } // 扩展成 80 个 32 位的块 for (int i = 16; i < 80; i++) { w[i] = ROTATE_LEFT(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); } // 初始化变量 a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; // 进行 80 次循环变换 for (int i = 0; i < 80; i++) { if (i < 20) { temp = ROTATE_LEFT(a, 5) + ((b & c) | ((~b) & d)) + e + w[i] + 0x5A827999; } else if (i < 40) { temp = ROTATE_LEFT(a, 5) + (b ^ c ^ d) + e + w[i] + 0x6ED9EBA1; } else if (i < 60) { temp = ROTATE_LEFT(a, 5) + ((b & c) | (b & d) | (c & d)) + e + w[i] + 0x8F1BBCDC; } else { temp = ROTATE_LEFT(a, 5) + (b ^ c ^ d) + e + w[i] + 0xCA62C1D6; } e = d; d = c; c = ROTATE_LEFT(b, 30); b = a; a = temp; } // 更新状态 state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; } // 定义函数 SHA1Init,用于初始化 SHA-1 的状态 void SHA1Init(SHA1_CTX *context) { memset(context, 0, sizeof(*context)); context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; } // 定义函数 SHA1Update,用于更新 SHA-1 的状态 void SHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len) { uint32_t i; uint32_t j; j = (context->count[0] >> 3) & 63; context->count[0] += len << 3; if (context->count[0] < (len << 3)) { context->count[1]++; } context->count[1] += len >> 29; if ((j + len) > 63) { memcpy(&context->buffer[j], data, (i = 64 - j)); SHA1Transform(context->state, context->buffer); for (; i + 63 < len; i += 64) { SHA1Transform(context->state, &data[i]); } j = 0; } else { i = 0; } memcpy(&context->buffer[j], &data[i], len - i); } // 定义函数 SHA1Final,用于输出 SHA-1 的结果 void SHA1Final(SHA1_CTX *context, uint8_t digest[20]) { uint32_t i; uint8_t finalcount[8]; for (i = 0; i < 8; i++) { finalcount[i] = (uint8_t) ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 0xFF); } SHA1Update(context, (const uint8_t *) "\200", 1); while ((context->count[0] & 504) != 448) { SHA1Update(context, (const uint8_t *) "\0", 1); } SHA1Update(context, finalcount, 8); for (i = 0; i < 20; i++) { digest[i] = (uint8_t) ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 0xFF); } memset(context, 0, sizeof(*context)); } ``` 在上面的代码中,`SHA1Init`、`SHA1Update` 和 `SHA1Final` 分别用于初始化 SHA-1 的状态、更新 SHA-1 的状态和输出 SHA-1 的结果。其中,`SHA1Update` 函数中的数据填充扩展操作在调用 `SHA1Transform` 函数之前完成。具体来说,`SHA1Update` 函数会将输入的数据分成若干个 64 字节的块,对于每个块,如果当前状态缓冲区中已经有部分数据,就先将输入数据填充到缓冲区中,直到缓冲区填满,然后再进行 SHA-1 的变换。如果当前输入数据不足一个块,就将输入数据填充到缓冲区中,等待后续输入数据的到来。`SHA1Final` 函数中的数据填充操作和 `SHA1Update` 函数类似,不过最后还需要将计数器的值填充到最后一个块中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值