Skip to content

Instantly share code, notes, and snippets.

@hirosof
Created February 11, 2011 05:53
Show Gist options
  • Save hirosof/821982 to your computer and use it in GitHub Desktop.
Save hirosof/821982 to your computer and use it in GitHub Desktop.
SHA1、SHA256、HMAC-SHA1、HMAC-SHA256、Shift-JIS->JIS、JIS->Shift-JIS、Base64エンコード・デコードの関数定義ファイル
/*
●SHA1、SHA256
●HMAC-SHA1、HMAC-SHA256
●Shift-JIS⇔JIS
●Base64エンコード・デコード
*/
//インクルード
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#ifndef __HiroSof_Func__
#define __HiroSof_Func__
//型定義
typedef unsigned __int32 SHA_INT_TYPE;
//構造体定義
//SHA1 return struct
typedef struct tagSHA1_DATA{
SHA_INT_TYPE Value[5];
char Val_String[45];
}SHA1_DATA;
//SHA256 return struct
typedef struct tagSHA256_DATA{
SHA_INT_TYPE Value[8];
char Val_String[72];
}SHA256_DATA;
//SHA1のメッセージダイジェスト初期値
const SHA_INT_TYPE SHA1_H_Val[] = { 0x67452301 , 0xefcdab89 , 0x98badcfe , 0x10325476 , 0xc3d2e1f0 };
//SHA256のメッセージダイジェスト初期値
const SHA_INT_TYPE SHA256_H_Val[] = { 0x6a09e667 , 0xbb67ae85 , 0x3c6ef372 , 0xa54ff53a ,
0x510e527f , 0x9b05688c , 0x1f83d9ab , 0x5be0cd19 } ;
//SHA256の加算定数
const SHA_INT_TYPE SHA256_K_Val[] = { 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 } ;
const char Base64_ChangeCharSet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//プロトタイプ宣言(基本関数)
SHA_INT_TYPE SHA1_K(SHA_INT_TYPE);
SHA_INT_TYPE SHA1_f(SHA_INT_TYPE,SHA_INT_TYPE,SHA_INT_TYPE,SHA_INT_TYPE);
SHA_INT_TYPE SHA1_rotl(SHA_INT_TYPE,SHA_INT_TYPE);
SHA_INT_TYPE SHA256_rotr(SHA_INT_TYPE,SHA_INT_TYPE);
SHA_INT_TYPE SHA256_sigma0(SHA_INT_TYPE);
SHA_INT_TYPE SHA256_sigma1(SHA_INT_TYPE);
SHA_INT_TYPE SHA256_sum0(SHA_INT_TYPE);
SHA_INT_TYPE SHA256_sum1(SHA_INT_TYPE);
SHA_INT_TYPE SHA256_ch(SHA_INT_TYPE,SHA_INT_TYPE,SHA_INT_TYPE);
SHA_INT_TYPE SHA256_maj(SHA_INT_TYPE,SHA_INT_TYPE,SHA_INT_TYPE);
void SHA_Reverse_INT64(const unsigned char *,unsigned __int64);
SHA_INT_TYPE SHA_Reverse(SHA_INT_TYPE);
//プロトタイプ宣言(SHA)
void SHA1_HashBlock(SHA_INT_TYPE *,const unsigned char *);
bool SHA1(SHA1_DATA *, const char* , SHA_INT_TYPE);
void SHA256_HashBlock(SHA_INT_TYPE *,const unsigned char *);
bool SHA256(SHA256_DATA *, const char* , SHA_INT_TYPE);
//プロトタイプ(HMAC)
bool HMAC_SHA1(SHA1_DATA *,const char*,const char*,SHA_INT_TYPE);
void HMAC_SHA1_Copy(const unsigned char*,SHA1_DATA*);
bool HMAC_SHA256(SHA256_DATA *,const char*,const char*,SHA_INT_TYPE);
void HMAC_SHA256_Copy(const unsigned char*,SHA256_DATA*);
//プロトタイプ
unsigned int base64_encode(char *,char *,bool);
unsigned int base64_decode(char *,char *,bool);
unsigned int sjisTojis(char *,char *);
unsigned int jisTosjis(char *,char *);
void base64_DecToBin_8(unsigned __int8,char *);
void base64_Reverse_8(char *);
void base64_DecToBin_6(unsigned __int8,char *);
void base64_Reverse_6(char *);
int base64_BinToDec_8(char *);
int base64_BinToDec_6(char *);
//基本関数
SHA_INT_TYPE SHA1_K(SHA_INT_TYPE t){
if(t<=19)return 0x5a827999;
else if(t<=39)return 0x6ed9eba1;
else if(t<=59)return 0x8f1bbcdc;
else if(t<=79)return 0xca62c1d6;
return 0;
}
SHA_INT_TYPE SHA1_f(SHA_INT_TYPE t,SHA_INT_TYPE B,SHA_INT_TYPE C, SHA_INT_TYPE D){
if(t<=19)return (B&C)|(~B&D);
else if(t<=39)return B^C^D;
else if(t<=59)return (B&C)|(B&D)|(C&D);
else if(t<=79)return B^C^D;
return 0;
}
//左ローテート関数
SHA_INT_TYPE SHA1_rotl(SHA_INT_TYPE r,SHA_INT_TYPE x){
SHA_INT_TYPE rot = r%32;
return (x >> (32 - rot)) | (x << rot);
}
void HMAC_SHA1_Copy(unsigned char *copy,SHA1_DATA *shd){
SHA_INT_TYPE Value[5];
for(int i=0;i<5;i++)Value[i] = SHA_Reverse(shd->Value[i]);
memcpy(copy,Value,20);
}
//右ローテート関数
SHA_INT_TYPE SHA256_rotr(SHA_INT_TYPE r,SHA_INT_TYPE x){
SHA_INT_TYPE rot = r%32;
return (x >> rot) | (x << (32-rot));
}
SHA_INT_TYPE SHA256_sigma0(SHA_INT_TYPE x){
return SHA256_rotr(7,x) ^ SHA256_rotr(18,x) ^ (x >> 3);
}
SHA_INT_TYPE SHA256_sigma1(SHA_INT_TYPE x){
return SHA256_rotr(17,x) ^ SHA256_rotr(19,x) ^ (x >> 10);
}
SHA_INT_TYPE SHA256_sum0(SHA_INT_TYPE x){
return SHA256_rotr(2,x) ^ SHA256_rotr(13,x) ^ SHA256_rotr(22,x);
}
SHA_INT_TYPE SHA256_sum1(SHA_INT_TYPE x){
return SHA256_rotr(6,x) ^ SHA256_rotr(11,x) ^ SHA256_rotr(25,x);
}
SHA_INT_TYPE SHA256_ch(SHA_INT_TYPE x,SHA_INT_TYPE y,SHA_INT_TYPE z){
return (x & y)^(~x & z);
}
SHA_INT_TYPE SHA256_maj(SHA_INT_TYPE x,SHA_INT_TYPE y,SHA_INT_TYPE z){
return (x&y)^(x&z)^(y&z);
}
void SHA_Reverse_INT64(unsigned char *data,unsigned __int64 write){
unsigned char cdata[8];
memcpy(cdata,&write,sizeof(__int64));
for(int i=0;i<=7;i++)*(data + i) = cdata[7-i];
}
SHA_INT_TYPE SHA_Reverse(SHA_INT_TYPE d){
unsigned char b_data[4],a_data[4];
SHA_INT_TYPE ret;
memcpy(b_data,&d,sizeof(__int32));
for(int i=0;i<4;i++)a_data[i] = b_data[3-i];
memcpy(&ret,a_data,sizeof(a_data));
return ret;
}
void HMAC_SHA256_Copy(unsigned char *copy,SHA256_DATA *shd){
SHA_INT_TYPE Value[8];
for(int i=0;i<8;i++)Value[i] = SHA_Reverse(shd->Value[i]);
memcpy(copy,Value,32);
}
void SHA1_HashBlock(SHA_INT_TYPE *SHA1_H_Data , const unsigned char *data){
SHA_INT_TYPE SIT[80];
SHA_INT_TYPE SIT_d[16] ;//512ビット、64バイト
SHA_INT_TYPE a,b,c,d,e;
for(int i=0,j=0;i<16;i++,j+=4){
SIT_d[i] = ((*(data + j +3)&0xFF) << 24)|((*(data + j + 2)&0xFF) << 16)|((*(data + j + 1)&0xFF) << 8)|((*(data + j)&0xFF));
}
for(int i=0;i<16;i++)SIT[i] = SHA_Reverse(SIT_d[i]);
for(int t=16;t<=79;t++)SIT[t] = SHA1_rotl(1,SIT[t-3]^SIT[t-8]^SIT[t-14]^SIT[t-16]);
a = *SHA1_H_Data;
b = *(SHA1_H_Data + 1);
c = *(SHA1_H_Data + 2);
d = *(SHA1_H_Data + 3);
e = *(SHA1_H_Data + 4);
for(int t=0;t<=79;t++){
SHA_INT_TYPE tmp;
tmp = SHA1_rotl(5,a)+SHA1_f(t,b,c,d)+e+SIT[t]+SHA1_K(t);
e = d;
d = c;
c = SHA1_rotl(30,b);
b=a;
a=tmp;
}
*SHA1_H_Data += a;
*(SHA1_H_Data+1)+=b;
*(SHA1_H_Data+2)+=c;
*(SHA1_H_Data+3)+=d;
*(SHA1_H_Data+4)+=e;
}
bool SHA1(SHA1_DATA *sha1d, const char *data , SHA_INT_TYPE size){
SHA_INT_TYPE s,h[5],ns;
int cnt=0;
unsigned __int64 s64;
unsigned char d[64];
if(!sha1d)return false;
s = (size)?size:strlen(data);
memcpy(h,SHA1_H_Val,sizeof(SHA1_H_Val));
//dataのバイト数が64バイトを超えていたら64バイト未満になるまで処理をする
for(SHA_INT_TYPE i=s,j=0;i>=64;i-=64,j+=64)SHA1_HashBlock(h,(const unsigned char*)(data + j));
//パディングに含めるデータのサイズ
ns = s%64;
//d・・・パディング文字列
memset(d,0,64);
//パディングにコピー
memcpy(d,data + (s-ns),ns);
//d[s]に0x80を代入
d[ns] = 0x80;
//パディングに含めるデータのサイズが56バイト以上だった時の処理
if(ns >= 56){
//パディングに含めるデータのサイズが56バイト以上だったらSHA1_HashBlockを実行する
SHA1_HashBlock(h,d);
//dの最初~56バイト文NULL文字をセット
memset(d,0,56);
}
//データのサイズをビット数にする
s64 = s*8;
//データのサイズ(ビット単位)を書き込む
SHA_Reverse_INT64(&d[56],s64);
//最後の処理
SHA1_HashBlock(h,d);
memcpy(sha1d->Value,h,sizeof(h));
sprintf(sha1d->Val_String,"%08X %08X %08X %08X %08X",h[0],h[1],h[2],h[3],h[4]);
return true;
}
bool HMAC_SHA1(SHA1_DATA *sha1d,const char *b_target,const char *b_key,SHA_INT_TYPE tsize){
unsigned char key[65],ipad[64],opad[64];
unsigned char *tk,tk2[20],tk3[84];
SHA_INT_TYPE tks;
SHA1_DATA SD,ret;
memset(&SD,0,sizeof(SHA1_DATA));
memset(key,0,65);
memset(ipad,0x36,64);
memset(opad,0x5c,64);
if(!sha1d)return false;
if(strlen(b_key) > 64){
SHA1(&SD,b_key,0);
HMAC_SHA1_Copy(key,&SD);
}else{
memcpy(key,(unsigned char*)b_key,strlen(b_key));
}
memset(&SD,0,sizeof(SHA1_DATA));
for(int i=0;i<64;i++){
ipad[i] = key[i] ^ ipad[i];
opad[i] = key[i] ^ opad[i];
}
tks = (tsize)?tsize:strlen(b_target) + 64;
tk = (unsigned char *)malloc(tks);
if(!tk)return false;
memset(tk,0,tks);
memcpy(tk,ipad,64);
memcpy(tk+64,(unsigned char*)b_target,(tsize)?tsize:strlen(b_target));
SHA1(&SD,(char *)tk,tks);
HMAC_SHA1_Copy(tk2,&SD);
memcpy(tk3,opad,64);
memcpy(tk3 + 64 , tk2,20);
SHA1(&ret,(char *)tk3,84);
memcpy(sha1d,&ret,sizeof(SHA1_DATA));
free(tk);
return true;
}
void SHA256_HashBlock(SHA_INT_TYPE *SHA256_H_Data,const unsigned char *data){
SHA_INT_TYPE SIT[64];
SHA_INT_TYPE SIT_d[16] ;//512ビット、64バイト
SHA_INT_TYPE a,b,c,d,e,f,g,h;
for(int i=0,j=0;i<16;i++,j+=4){
SIT_d[i] = ((*(data + j +3)&0xFF) << 24)|((*(data + j + 2)&0xFF) << 16)|((*(data + j + 1)&0xFF) << 8)|((*(data + j)&0xFF));
}
for(int i=0;i<16;i++)SIT[i] = SHA_Reverse(SIT_d[i]);
for(int t=16;t<=63;t++) SIT[t] = SHA256_sigma1(SIT[t-2]) + SIT[t-7] + SHA256_sigma0(SIT[t-15]) + SIT[t-16];
a = *SHA256_H_Data;
b = *(SHA256_H_Data + 1);
c = *(SHA256_H_Data + 2);
d = *(SHA256_H_Data + 3);
e = *(SHA256_H_Data + 4);
f = *(SHA256_H_Data + 5);
g = *(SHA256_H_Data + 6);
h = *(SHA256_H_Data + 7);
for(int t=0;t<=63;t++){
SHA_INT_TYPE tmp[2];
tmp[0] = h + SHA256_sum1(e) + SHA256_ch(e,f,g) + SHA256_K_Val[t] +SIT[t];
tmp[1] = SHA256_sum0(a) + SHA256_maj(a,b,c);
h = g;
g = f;
f = e;
e = d + tmp[0];
d = c;
c = b;
b = a;
a = tmp[0] + tmp[1];
}
*SHA256_H_Data += a;
*(SHA256_H_Data + 1) += b;
*(SHA256_H_Data + 2) += c;
*(SHA256_H_Data + 3) += d;
*(SHA256_H_Data + 4) += e;
*(SHA256_H_Data + 5) += f;
*(SHA256_H_Data + 6) += g;
*(SHA256_H_Data + 7) += h;
}
bool SHA256(SHA256_DATA *sha256d, const char *data , SHA_INT_TYPE size){
SHA_INT_TYPE s,h[8],ns;
int cnt=0;
unsigned __int64 s64;
unsigned char d[64];
if(!sha256d)return false;
s = (size)?size:strlen(data);
memcpy(h,SHA256_H_Val,sizeof(SHA256_H_Val));
//dataのバイト数が64バイトを超えていたら60バイト未満になるまで処理をする
for(SHA_INT_TYPE i=s,j=0;i>=64;i-=64,j+=64)SHA256_HashBlock(h,(const unsigned char*)(data + j));
//パディングに含めるデータのサイズ
ns = s%64;
//d・・・パディング文字列
memset(d,0,64);
//パディングにコピー
memcpy(d,data + (s-ns),ns);
//d[ns]に0x80を代入
d[ns] = 0x80;
//パディングに含めるデータのサイズが56バイト以上だった時の処理
if(ns >= 56){
//パディングに含めるデータのサイズが56バイト以上だったらSHA256_HashBlockを実行する
SHA256_HashBlock(h,d);
//dの最初~56バイト文NULL文字をセット
memset(d,0,56);
}
//データのサイズをビット数にする
s64 = s*8;
//データのサイズ(ビット単位)を書き込む
SHA_Reverse_INT64(&d[56],s64);
//最後の処理
SHA256_HashBlock(h,d);
memcpy(sha256d->Value,h,sizeof(h));
sprintf(sha256d->Val_String,"%08X %08X %08X %08X %08X %08X %08X %08X",h[0],h[1],h[2],h[3],h[4],h[5],h[6],h[7]);
return true;
}
bool HMAC_SHA256(SHA256_DATA *sha256d,const char *b_target,const char *b_key,SHA_INT_TYPE tsize){
unsigned char key[65],ipad[64],opad[64];
unsigned char *tk,tk2[32],tk3[96];
SHA_INT_TYPE tks;
SHA256_DATA SD,ret;
memset(&SD,0,sizeof(SHA256_DATA));
memset(key,0,65);
memset(ipad,0x36,64);
memset(opad,0x5c,64);
if(!sha256d)return false;
if(strlen(b_key) > 64){
SHA256(&SD,b_key,0);
HMAC_SHA256_Copy(key,&SD);
}else{
memcpy(key,(unsigned char*)b_key,strlen(b_key));
}
memset(&SD,0,sizeof(SHA256_DATA));
for(int i=0;i<64;i++){
ipad[i] = key[i] ^ ipad[i];
opad[i] = key[i] ^ opad[i];
}
tks = (tsize)?tsize:strlen(b_target) + 64;
tk = (unsigned char *)malloc(tks);
if(!tk)return false;
memset(tk,0,tks);
memcpy(tk,ipad,64);
memcpy(tk+64,(unsigned char*)b_target,(tsize)?tsize:strlen(b_target));
SHA256(&SD,(char *)tk,tks);
HMAC_SHA256_Copy(tk2,&SD);
memcpy(tk3,opad,64);
memcpy(tk3 + 64 , tk2,32);
SHA256(&ret,(char *)tk3,96);
memcpy(sha256d,&ret,sizeof(SHA256_DATA));
free(tk);
return true;
}
//Shift-JIS -> JIS
unsigned int sjisTojis(char *in,char *out){
unsigned int ins,outs,pos,outpos;
unsigned char *pin,*pout,c,high,low;
const unsigned char mbs[]={0x1b,0x24,0x42};
const unsigned char mbe[]={0x1b,0x28,0x42};
bool mbc;
//入力文字列のバイト数取得
ins = strlen(in);
pos = 0;
outs = 0;
mbc = false;
pin = (unsigned char*)in;
//必要なバッファの数を計算するブロック
while(1){
c = *(pin + pos);
if(((c>=129)&&(c<=159))||((c>=224)&&(c<=252))){
if(!mbc){
outs+=3;
mbc = true;
}
outs+=2;
pos+=2;
}else{
if(mbc){
outs+=3;
mbc = false;
}
outs++;
pos++;
}
if(pos >= ins){
if(mbc){
outs+=3;
mbc = false;
}
break;
}
}
if(!out)return outs + 1; //+1はNULL文字用
pos = outpos = 0;
pout = (unsigned char*)out;
mbc = 0;
//実際に変換するブロック
while(1){
c = *(pin + pos);
if(((c>=129)&&(c<=159))||((c>=224)&&(c<=252))){
if(!mbc){
memcpy(pout + outpos , mbs , 3);
outpos+=3;
mbc = true;
}
high = c;
low = *(pin + pos + 1);
if(high <= 0x9f)high-=0x71;
else high-=0xb1;
high = high*2+1;
if(low > 0x7f)low-=0x01;
if(low >= 0x9e){
low-=0x7d;
high++;
}else{
low-=0x1f;
}
*(pout + outpos) = high;
*(pout + outpos + 1) = low;
outpos+=2;
pos+=2;
}else{
if(mbc){
memcpy(pout + outpos , mbe , 3);
outpos+=3;
mbc = false;
}
*(pout + outpos) = c;
outpos++;
pos++;
}
if(pos >= ins){
if(mbc){
memcpy(pout + outpos , mbe , 3);
outpos+=3;
mbc = false;
}
break;
}
}
*(pout + outs)=0;
return outs;
}
//JIS -> Shift-JIS
unsigned int jisTosjis(char *in,char *out){
unsigned int ins,outs,pos,outpos;
unsigned char *pin,*pout,c,sc[2],high,low;
const unsigned char mbs[]={0x1b,0x24,0x42};
const unsigned char mbe[]={0x1b,0x28,0x42};
bool mbc;
ins = 0;
pos = 0;
outs = 0;
mbc = false;
pin = (unsigned char*)in;
//必要なバッファの数を計算するブロック
while(1){
c = *(pin + pos);
if(!c)break;
ins++;
if(c==mbs[0]){
pos+=3;
}else{
pos++;
outs++;
}
}
if(!out)return outs + 1; //+1はNULL文字用
pos = outpos = 0;
pout = (unsigned char*)out;
mbc = 0;
while(1){
c = *(pin + pos);
if(!c)break;
if(c==0x1b){
sc[0] = *(pin + pos + 1);
if(sc[0]==mbs[1])mbc = true;
else if(sc[0]==mbe[1])mbc = false;
pos+=3;
}else{
if(mbc){
high = c;
low = *(pin + pos + 1);
if(high%2)low+=0x1f;
else low+=0x7d;
if(low >=0x7f)low++;
high = (high-0x21)/2 + 0x81;
if(high >= 0x9f)high+=0x40;
*(pout + outpos) = high;
*(pout + outpos + 1) = low;
pos+=2;
outpos+=2;
}else{
*(pout + outpos) = c;
pos++;
outpos++;
}
}
}
*(pout + outs)=0;
return 0;
}
void base64_Reverse_8(char *txt){
char b_txt[8];
//txt ⇒ b_txt
for(int i=0;i<8;i++)b_txt[i]=*(txt + i);
//b_txt ⇒ txt
for(int i=0;i<8;i++)*(txt + i) = b_txt[7-i];
}
void base64_Reverse_6(char *txt){
char b_txt[6];
//txt ⇒ b_txt
for(int i=0;i<6;i++)b_txt[i]=*(txt + i);
//b_txt ⇒ txt
for(int i=0;i<6;i++)*(txt + i) = b_txt[5-i];
}
void base64_DecToBin_8(unsigned __int8 in,char *out){
char b_bin[9];
unsigned __int8 b_in;
memset(b_bin,0,9);
b_in = in;
while(1){
sprintf(b_bin,"%s%d",b_bin,b_in%2);
b_in/=2;
if(!b_in)break;
}
memcpy(out,b_bin,strlen(b_bin));
memset(out + strlen(b_bin),'0',8-strlen(b_bin));
base64_Reverse_8(out);
}
void base64_DecToBin_6(unsigned __int8 in,char *out){
char b_bin[7];
unsigned __int8 b_in;
memset(b_bin,0,7);
b_in = in;
while(1){
sprintf(b_bin,"%s%d",b_bin,b_in%2);
b_in/=2;
if(!b_in)break;
}
memcpy(out,b_bin,strlen(b_bin));
memset(out + strlen(b_bin),'0',6-strlen(b_bin));
base64_Reverse_6(out);
}
int base64_BinToDec_8(char *in){
int d = 128,dec=0;
for(int i=0;i<8;i++){
if(*(in + i) == '1')dec+=d;
d/=2;
}
return dec;
}
int base64_BinToDec_6(char *in){
int d = 32,dec=0;
for(int i=0;i<6;i++){
if(*(in + i) == '1')dec+=d;
d/=2;
}
return dec;
}
unsigned int base64_encode(char *in,char *out,bool isJIS){
char *jisstring,*binstring,*retstring;
unsigned int retsize,binsize,jissize,push0,pushchar;
//各種サイズの計算
jissize = (isJIS)?sjisTojis(in,0) - 1:strlen(in);
binsize = jissize * 8;
if(binsize%6)binsize += push0 = 6-binsize%6;
else push0 = 0;
retsize = binsize/6;
if(retsize%4)retsize += pushchar = 4-retsize%4;
else pushchar=0;
if(!out)return retsize + 1;
//各種メモリ確保
jisstring = (char *)malloc(jissize + 1);
binstring = (char *)malloc(binsize + 1);
retstring = (char *)malloc(retsize + 1);
//各種初期化
memset(jisstring,0,jissize + 1);
memset(binstring,0,binsize + 1);
memset(retstring,0,retsize + 1);
//SJIS ⇒ JIS変換 or copy
if(isJIS)sjisTojis(in,jisstring);
else memcpy(jisstring,in,strlen(in));
//JISコード or Shift-JIS ⇒2進数
for(int i=0;i<jissize;i++)base64_DecToBin_8(*(jisstring+i),binstring + (8*i));
//'0'を挿入
memset(binstring + strlen(binstring),'0',push0);
//2進数⇒base64
for(int i=0;i<binsize/6;i++){
int id;
id = base64_BinToDec_6(binstring + (6*i));
*(retstring + i) = Base64_ChangeCharSet[id];
}
//'='を挿入
memset(retstring + strlen(retstring),'=',pushchar);
//結果をコピー
memcpy(out,retstring,retsize);
//各種解放
free(jisstring);
free(binstring);
free(retstring);
return retsize;
}
unsigned int base64_decode(char *in,char *out,bool isJIS){
char *b64string,*binstring,*retstring;
unsigned int b64_size,binsize_b64,binsize,retsize;
unsigned int equalnum=0;
//各種計算
//最後の=の数の計算
for(int i=0;i<3;i++){
if(*(in + strlen(in) - 1 - i) != '=')break;
equalnum++;
}
b64_size = strlen(in) - equalnum;
binsize_b64 = b64_size*6;
binsize = binsize_b64 - binsize_b64%8;
retsize = binsize/8;
if(!out)return retsize + 1;
//各種メモリ確保
b64string = (char *)malloc(b64_size + 1);
binstring = (char *)malloc(binsize_b64 + 1);
retstring = (char *)malloc(retsize + 1);
//各種初期化
memset(b64string,0,b64_size + 1);
memset(binstring,0,binsize_b64 + 1);
memset(retstring,0,retsize + 1);
//Base64をコピー
memcpy(b64string,in,b64_size);
//Base64 ⇒ 2進数
for(int i=0;i<b64_size;i++){
unsigned __int8 dec=0;
for(int j=0;j<64;j++){
if(Base64_ChangeCharSet[j] == *(b64string + i)){
dec = j;
break;
}
}
base64_DecToBin_6(dec,binstring + i*6);
}
//2進数⇒JISコード or Shift-JIS
for(int i=0;i<retsize;i++){
*(retstring + i) = base64_BinToDec_8(binstring + i*8);
}
if(isJIS){
retsize = jisTosjis(retstring,0);
jisTosjis(retstring,out);
}else{
memcpy(out,retstring,strlen(retstring));
}
//各種解放
free(b64string);
free(binstring);
free(retstring);
return retsize;
}
#endif /* HiroSof_Func */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment