#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include <stdbool.h>
#define SIZE 2
typedef unsigned int u32;
typedef unsigned char u8;
typedef unsigned long long u64;
#define H0 0x6a09e667
#define H1 0xbb67ae85
#define H2 0x3c6ef372
#define H3 0xa54ff53a
#define H4 0x510e527f
#define H5 0x9b05688c
#define H6 0x1f83d9ab
#define H7 0x5be0cd19
struct DataItem {
struct DataItem* next;
unsigned char* data;
};
struct temp_total_arr_{
struct temp_total_arr_* next;
unsigned char word[100];
};
struct count_list{
struct count_list* next;
unsigned char* word;
int num;
};
u32 Wt[64];
u32 Kt[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 };
u32 Ch(u32 x, u32 y, u32 z)
{
return (x & y) ^ (~x & z);
}
u32 cycle_rshift(u32 x,u32 n)
{
return ((x & (((u32)1 << n) - 1)) << (32 - n))|(x >> n);
}
u32 Sum0(u32 x)
{
return cycle_rshift(x, 2) ^ cycle_rshift(x, 13) ^ cycle_rshift(x, 22);
}
u32 Sum1(u32 x)
{
return cycle_rshift(x, 6) ^ cycle_rshift(x, 11) ^ cycle_rshift(x, 25);
}
u32 Sigma0(u32 x)
{
return cycle_rshift(x, 7) ^ cycle_rshift(x, 18) ^ (x>>3);
}
u32 Sigma1(u32 x)
{
return cycle_rshift(x, 17) ^ cycle_rshift(x, 19) ^ (x >> 10);
}
u32 Ma(u32 x, u32 y, u32 z)
{
return (x & y) ^ (x & z)^ (y & z);
}
struct sha256
{
u32 block[16]; //加密的measage
u32 hash[8]; //hash的结果
u64 hash_length;//总共hash的byte数
u8 offset; //一个update未对齐Word(4字节)的字节数
u8 index; //当前已经写到block的位置
};
void sha_init(struct sha256 *s)
{
s->hash[0] = H0;
s->hash[1] = H1;
s->hash[2] = H2;
s->hash[3] = H3;
s->hash[4] = H4;
s->hash[5] = H5;
s->hash[6] = H6;
s->hash[7] = H7;
s->hash_length = 0;
s->index = 0;
s->offset = 0;
}
void sha_caculator(struct sha256* s)//先补齐 Wt,然后循环64次加密
{
u8 i = 0;
u32 m0, s0, s1,c1,t1;
u32 temp[8];
for(i=0;i<8;i++)
temp[i]=s->hash[i];
for (i = 0; i < 16; i++)
Wt[i] = s->block[i];
for (i = 16; i < 64; i++)
Wt[i] = Sigma1(Wt[i-2])+ Wt[i-7]+Sigma0(Wt[i - 15])+ Wt[i - 16];
for (i = 0; i < 64; i++)
{
s0 = Sum0(temp[0]);
s1 = Sum1(temp[4]);
m0 = Ma(temp[0], temp[1], temp[2]);
c1 = Ch(temp[4], temp[5], temp[6]);
t1 = s1+c1+temp[7]+Wt[i] + Kt[i];
temp[7] = temp[6];
temp[6] = temp[5];
temp[5] = temp[4];
temp[4] = temp[3]+ t1;
temp[3] = temp[2];
temp[2] = temp[1];
temp[1] = temp[0];
temp[0] = t1+m0+s0;
}
for (i = 0; i < 8; i++)
s->hash[i]+=temp[i];
}
void sha_updata(struct sha256* s,unsigned char *str,u64 len)
{
u64 i = 0;
u64 count;
s->hash_length += len;
if (s->offset!=0)//说明没有4字节对齐
{
if (s->offset + len < 4)
{
for (i = s->offset; i < s->offset+len; i++)
{
s->block[s->index] |= (((u32)(*str)) << (8 * (3 - i)));
str++;
}
s->offset += len;
return;
}
else
{
len = len + s->offset - 4;
for (i = s->offset; i < 4; i++)
{
s->block[s->index] |= (((u32)(*str)) << (8 * (3 - i)));
str++;
}
s->index++;
if (s->index == 16)
{
sha_caculator(s);//满足512bit 16Word加密一次
s->index = 0;
}
}
}
count = (len >> 2);//计算这次加密有多少个Word
s->offset = len % 4;//对齐Word剩余的byte
for(i=0;i<count;i++)
{
s->block[s->index] = (((u32)(*str)) << 24) |
((*(str + 1)) << 16) |
((*(str + 2)) << 8) |
(*(str + 3));
s->index++;
str += 4;
if (s->index == 16)
{
sha_caculator(s);//满足512bit 16Word加密一次
s->index = 0;
}
}
s->block[s->index] = 0;//对齐Word剩余的byte写在 s->index 位置上,供下一次update使用
for (i = 0; i < s->offset; i++)
{
s->block[s->index] |= (((u32)(*str)) << (8 * (3 - i)));
str++;
}
}
void sha_final(struct sha256* s)
{
u8 temp=s->hash_length % 64;//计算需要填充多少byte
u8 fill[4] = { 0x80,0x0,0x0,0x0 };
u32 i;
if (temp == 56)//则需要填充一个512bit
{
//补齐前一次的512bit
if (s->offset != 0)
{
for (i = 0; i < 4-s->offset; i++)
s->block[s->index] |= (fill[i]<< (8 * (3 - i-s->offset)));
s->index++;
}
else
{
s->block[s->index] = 0x80000000;
s->index++;
}
for (i = s->index; i < 16; i++)
s->block[i] = 0;
sha_caculator(s);
for(i=0;i<14;i++)
s->block[i] = 0;
s->block[14] = s->hash_length >> 29;
s->block[15] = s->hash_length << 3 & 0xffffffff;
sha_caculator(s);
}
else
{
if (s->offset != 0)
{
for (i = 0; i < 4-s->offset; i++)
s->block[s->index] |= (fill[i] << (8 * ( 3 - i - s->offset)));
s->index++;
}
else
{
s->block[s->index] = 0x80000000;
s->index++;
}
for (i = s->index; i < 14; i++)
s->block[i] = 0;
s->block[14] = s->hash_length>> 29;
s->block[15] = s->hash_length<<3 & 0xffffffff;
sha_caculator(s);
}
}
int hasher(unsigned char* in){
int sum = 0;
struct sha256 testsha;
sha_init(&testsha);
sha_updata(&testsha, in, strlen(in));
sha_final(&testsha);
sum=testsha.hash[0]%SIZE;
return sum;
}
struct temp_total_arr_* words(unsigned char* in,struct temp_total_arr_* temp_total_arr){
int totalappendindex=0;
int times=strlen(in)+1;
unsigned char tempdata_char[1];
struct temp_total_arr_* temptotalarray;
for(int i=0;i<times;i++){
strncpy(tempdata_char,in+i,1);
if((strcmp(tempdata_char," ")==0) || (i==times-1)){
temptotalarray= (struct temp_total_arr_*) malloc(sizeof(struct temp_total_arr_));
strncpy(temptotalarray->word,in+totalappendindex,i-totalappendindex);
temptotalarray->next=temp_total_arr;
temp_total_arr=temptotalarray;
totalappendindex=i+1;
}
}
return temp_total_arr;
}
int query(unsigned char* in,struct DataItem* hashArray[SIZE]){
int key=hasher(in);
struct DataItem* item;
item = hashArray[key];
while(item!=NULL){
if(strcmp(in,item->data)==0){
return 1;
}
item=item->next;
}
return 0;
}
struct count_list* query2(unsigned char* in,struct count_list* count){
struct count_list* item;
item = count;
struct count_list* tempitem=(struct count_list*) malloc(sizeof(struct count_list));
while(item->next!=NULL){
if(strcmp(in,item->word)==0){
item->num++;
return count;
}
item=item->next;
}
tempitem->num=1;
tempitem->word=in;
tempitem->next=count;
count=tempitem;
return count;
}
struct count_list* search(unsigned char* in,struct temp_total_arr_* temp_total_arr,struct DataItem* hashArray[SIZE]){
temp_total_arr=words(in,temp_total_arr);
struct count_list* count=(struct count_list*) malloc(sizeof(struct count_list));
int answer;
while(temp_total_arr->next!=NULL){
answer=query(temp_total_arr->word,hashArray);
if(answer==1){//1 means in hashtable
count=query2(temp_total_arr->word,count);
}
temp_total_arr=temp_total_arr->next;
}
return count;
}
int delete(unsigned char* data,struct temp_total_arr_* temp_total_arr,struct DataItem* hashArray[SIZE]){
int index=hasher(data);
if(hashArray[index]!=NULL){
if(strcmp(hashArray[index]->data,data)==0){
hashArray[index]=hashArray[index]->next;
return 0;
}
}else{
return 0;
}
struct DataItem* newitem;
newitem=hashArray[index];
while(newitem!=NULL && newitem->next!=NULL){
if(strcmp(newitem->next->data,data)==0){
newitem->next=newitem->next->next;
}
newitem=newitem->next;
}
return 0;
}
int insert(unsigned char* data,struct DataItem* hashArray[SIZE]){
int answer;
answer=query(data,hashArray);
if(answer==1){
return 1;
}
struct DataItem *item = (struct DataItem*) malloc(sizeof(struct DataItem));
item->data = data;
item->next=NULL;
int index=hasher(data);
item->next=hashArray[index];
hashArray[index] = item;
return 0;
}
int main(int argc,char*argv[])
{
struct count_list* totalcount=(struct count_list*) malloc(sizeof(struct count_list));
struct temp_total_arr_* temp_total_arr;
struct DataItem* hashArray[SIZE];
temp_total_arr=(struct temp_total_arr_*) malloc(sizeof(struct temp_total_arr_));
int m=1;
int n=1;
int return_value=0;
int indexer;
int indexer2;
unsigned char* nihao;
unsigned char* zaijian;
unsigned char* shuijiao;
for(indexer=0;indexer<SIZE;indexer++){
hashArray[indexer]=NULL;
}
nihao="apple";
return_value=insert(nihao,hashArray);
zaijian="banana";
return_value=insert(zaijian,hashArray);
shuijiao="orange";
return_value=insert(shuijiao,hashArray);
return_value=insert("a",hashArray);
return_value=insert("b",hashArray);
return_value=insert("c",hashArray);
return_value=insert("d",hashArray);
unsigned char* input="apple banana orange banana apple pineapple apple banana";
unsigned char* input2="banana";
return_value=delete(input2,temp_total_arr,hashArray);
return_value=delete(input2,temp_total_arr,hashArray);
totalcount = search(input,temp_total_arr,hashArray);
while(totalcount->next!=NULL){
printf("%s,%d\n",totalcount->word,totalcount->num);
totalcount=totalcount->next;
}
/*
orange,1
apple,3
*/
}//printf("%d\n",__LINE__);