#include<stdio.h>
#include<string.h>
#include<limits.h>
#include<stdint.h>
#define BUFSIZE 48
#define NUMENCDATA 4
void printb( unsigned int v) {
unsigned int mask = ( int ) 1 << ( sizeof ( v) * CHAR_BIT - 1 ) ;
while ( mask >>= 1 ) ;
}
void putb( unsigned int v) {
}
static const size_t sixbase = 0b111111 ;
static const size_t eigbase = 0b11111111 ;
static const char table[ ] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ;
enum State { First = 1 , Second = 2 , Third = 3 , Finish = 4 } ;
typedef struct {
size_t bytes;
size_t eqNum;
uint8_t org[ 3 ] ;
enum State state;
} FSM;
static FSM initState = { 0 , 0 , { 0 } , First } ;
void FSM_init( FSM * self) {
* self = initState;
}
void FSM_stack( FSM * self, uint8_t c) {
size_t stack = ( size_t ) c;
switch ( self-> state) {
case First:
self-> bytes = ( stack << 16 ) ;
self-> state = Second;
self-> org[ 0 ] = c;
break ;
case Second:
self-> bytes = self-> bytes | ( stack << 8 ) ;
self-> state = Third;
self-> org[ 1 ] = c;
break ;
case Third:
self-> bytes = self-> bytes | stack;
self-> state = Finish;
self-> org[ 2 ] = c;
break ;
case Finish:
break ;
}
}
void FSM_encode_flush( FSM * self) {
uint8_t res[ NUMENCDATA] ;
if ( self-> state == Finish) {
for ( size_t it = 0 ; it != NUMENCDATA; ++ it) {
res[ it] = table[ ( self-> bytes & ( sixbase << ( 18 - 6 * it) ) ) >> ( 18 - 6 * it) ] ;
}
fwrite ( res
, sizeof ( uint8_t ) , 2 , stdout
) ; if ( self-> eqNum == 2 ) {
}
if ( self-> eqNum == 1 ) {
fwrite ( res
+ 2 , sizeof ( uint8_t ) , 1 , stdout
) ; }
if ( self-> eqNum == 0 ) {
fwrite ( res
+ 2 , sizeof ( uint8_t ) , 2 , stdout
) ; }
// printf(" : ");
// printf("%c%c%c :",self->org[0], self->org[1], self->org[2]);
// putb(self->bytes);
* self = initState;
}
}
void FSM_pre_terminal_proc( FSM * self) {
switch ( self-> state) {
case First:
break ;
case Second:
self-> eqNum = 2 ;
FSM_stack( self, 0 ) ;
FSM_stack( self, 0 ) ;
break ;
case Third:
self-> eqNum = 1 ;
FSM_stack( self, 0 ) ;
break ;
case Finish:
break ;
}
return ;
}
void b64enc( FILE * fp) {
FSM fsm;
FSM_init( & fsm) ;
uint8_t buf[ BUFSIZE] ;
size_t nread;
while ( ( nread
= fread ( buf
, sizeof ( uint8_t ) , BUFSIZE
, fp
) ) > 0 ) { for ( size_t it = 0 ; it != nread; ++ it) {
FSM_stack( & fsm, buf[ it] ) ;
FSM_encode_flush( & fsm) ;
}
FSM_pre_terminal_proc( & fsm) ;
FSM_encode_flush( & fsm) ;
}
}
}
int main( void ) {
FILE * fp;
if ( fopen_s( & fp, "base64s.c" , "rb" ) < 0 ) {
fprintf ( stderr
, "ファイルを開けませんでした!\n " ) ; return 1 ;
}
b64enc( fp) ;
return 0 ;
}
//
I2luY2x1ZGU8c3RkaW8uaD4KI2luY2x1ZGU8c3RyaW5nLmg+CiNpbmNsdWRlPGxpbWl0cy5oPgojaW5jbHVkZTxzdGRpbnQuaD4KCiNkZWZpbmUgQlVGU0laRSA0OAojZGVmaW5lIE5VTUVOQ0RBVEEgNAoKdm9pZCBwcmludGIodW5zaWduZWQgaW50IHYpIHsKICB1bnNpZ25lZCBpbnQgbWFzayA9IChpbnQpMSA8PCAoc2l6ZW9mKHYpICogQ0hBUl9CSVQgLSAxKTsKICBkbyBwdXRjaGFyKG1hc2sgJiB2ID8gJzEnIDogJzAnKTsKICB3aGlsZSAobWFzayA+Pj0gMSk7Cn0KCnZvaWQgcHV0Yih1bnNpZ25lZCBpbnQgdikgewogIHB1dGNoYXIoJzAnKSwgcHV0Y2hhcignYicpLCBwcmludGIodiksIHB1dGNoYXIoJ1xuJyk7Cn0KCnN0YXRpYyBjb25zdCBzaXplX3Qgc2l4YmFzZSA9IDBiMTExMTExOwpzdGF0aWMgY29uc3Qgc2l6ZV90IGVpZ2Jhc2UgPSAwYjExMTExMTExOwpzdGF0aWMgY29uc3QgY2hhciB0YWJsZVtdID0gIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8iOwoKZW51bSBTdGF0ZSB7IEZpcnN0ID0gMSwgU2Vjb25kID0gMiwgVGhpcmQgPSAzLCBGaW5pc2ggPSA0IH07CnR5cGVkZWYgc3RydWN0IHsKICAgIHNpemVfdCBieXRlczsKICAgIHNpemVfdCBlcU51bTsKICAgIHVpbnQ4X3Qgb3JnWzNdOwogICAgZW51bSBTdGF0ZSBzdGF0ZTsKfSBGU007CgpzdGF0aWMgRlNNIGluaXRTdGF0ZSA9IHsgMCwgMCwgezB9LCBGaXJzdCB9OwoKCnZvaWQgRlNNX2luaXQoRlNNICpzZWxmKSB7CiAgICAqc2VsZiA9IGluaXRTdGF0ZTsKfQoKdm9pZCBGU01fc3RhY2soRlNNICpzZWxmLCB1aW50OF90IGMpIHsKICAgIHNpemVfdCBzdGFjayA9IChzaXplX3QpYzsKICAgIHN3aXRjaCAoc2VsZi0+c3RhdGUpIHsKICAgICAgICBjYXNlIEZpcnN0OgogICAgICAgICAgICBzZWxmLT5ieXRlcyA9IChzdGFjayA8PCAxNik7CiAgICAgICAgICAgIHNlbGYtPnN0YXRlID0gU2Vjb25kOwogICAgICAgICAgICBzZWxmLT5vcmdbMF0gPSBjOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFNlY29uZDoKICAgICAgICAgICAgc2VsZi0+Ynl0ZXMgPSBzZWxmLT5ieXRlcyB8IChzdGFjayA8PCA4KSA7CiAgICAgICAgICAgIHNlbGYtPnN0YXRlID0gVGhpcmQ7CiAgICAgICAgICAgIHNlbGYtPm9yZ1sxXSA9IGM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVGhpcmQ6CiAgICAgICAgICAgIHNlbGYtPmJ5dGVzID0gc2VsZi0+Ynl0ZXMgfCBzdGFjazsKICAgICAgICAgICAgc2VsZi0+c3RhdGUgPSBGaW5pc2g7CiAgICAgICAgICAgIHNlbGYtPm9yZ1syXSA9IGM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRmluaXNoOgogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwi44K544K/44OD44Kv44GM44GE44Gj44Gx44GE44Gn44GZ44CCXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9Cn0KCnZvaWQgRlNNX2VuY29kZV9mbHVzaChGU00gKnNlbGYpIHsKICAgIHVpbnQ4X3QgcmVzW05VTUVOQ0RBVEFdOwogICAgaWYoc2VsZi0+c3RhdGUgPT0gRmluaXNoKSB7IAogICAgICAgIGZvcihzaXplX3QgaXQgPSAwOyBpdCAhPSBOVU1FTkNEQVRBOyArK2l0KSB7CiAgICAgICAgICAgIHJlc1tpdF0gPSB0YWJsZVsoc2VsZi0+Ynl0ZXMgJiAoc2l4YmFzZSA8PCAoMTggLSA2ICogaXQpKSkgPj4gKDE4IC0gNiAqIGl0KV07CiAgICAgICAgfQogICAgICAgIGZ3cml0ZShyZXMsIHNpemVvZih1aW50OF90KSwgMiwgc3Rkb3V0KTsKICAgICAgICBpZihzZWxmLT5lcU51bSA9PSAyKSB7IAogICAgICAgICAgICBwcmludGYoIj09Iik7CiAgICAgICAgfQogICAgICAgIGlmKHNlbGYtPmVxTnVtID09IDEpIHsKICAgICAgICAgICAgZndyaXRlKHJlcysyLCBzaXplb2YodWludDhfdCksIDEsIHN0ZG91dCk7CiAgICAgICAgICAgIHByaW50ZigiPSIpOwogICAgICAgIH0KICAgICAgICBpZihzZWxmLT5lcU51bSA9PSAwKSB7CiAgICAgICAgICAgIGZ3cml0ZShyZXMrMiwgc2l6ZW9mKHVpbnQ4X3QpLCAyLCBzdGRvdXQpOwogICAgICAgIH0KLy8gICAgICAgIHByaW50ZigiIDogIik7Ci8vICAgICAgICBwcmludGYoIiVjJWMlYyA6IixzZWxmLT5vcmdbMF0sIHNlbGYtPm9yZ1sxXSwgc2VsZi0+b3JnWzJdKTsKLy8gICAgICAgIHB1dGIoc2VsZi0+Ynl0ZXMpOwogICAgICAgICpzZWxmID0gaW5pdFN0YXRlOwogICAgfQp9Cgp2b2lkIEZTTV9wcmVfdGVybWluYWxfcHJvYyhGU00gKnNlbGYpIHsKICAgIHN3aXRjaCAoc2VsZi0+c3RhdGUpIHsKICAgICAgICBjYXNlIEZpcnN0OgogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFNlY29uZDoKICAgICAgICAgICAgc2VsZi0+ZXFOdW0gPSAyOwogICAgICAgICAgICBGU01fc3RhY2soc2VsZiwwKTsKICAgICAgICAgICAgRlNNX3N0YWNrKHNlbGYsMCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVGhpcmQ6CiAgICAgICAgICAgIHNlbGYtPmVxTnVtID0gMTsKICAgICAgICAgICAgRlNNX3N0YWNrKHNlbGYsMCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRmluaXNoOgogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybjsKfQoKCnZvaWQgYjY0ZW5jKEZJTEUgKmZwKSB7CiAgICBGU00gZnNtOwogICAgRlNNX2luaXQoJmZzbSk7CiAgICB1aW50OF90IGJ1ZltCVUZTSVpFXTsKICAgIHNpemVfdCBucmVhZDsKICAgIHdoaWxlKChucmVhZCA9IGZyZWFkKGJ1Ziwgc2l6ZW9mKHVpbnQ4X3QpLCBCVUZTSVpFLCBmcCkpID4gMCkgewogICAgICAgIGZvcihzaXplX3QgaXQgPSAwOyBpdCAhPSBucmVhZDsgKytpdCkgewogICAgICAgICAgICBGU01fc3RhY2soJmZzbSwgYnVmW2l0XSk7CiAgICAgICAgICAgIEZTTV9lbmNvZGVfZmx1c2goJmZzbSk7CiAgICAgICAgfQogICAgICAgIGlmKGZlb2YoZnApKSB7CiAgICAgICAgICAgIEZTTV9wcmVfdGVybWluYWxfcHJvYygmZnNtKTsKICAgICAgICAgICAgRlNNX2VuY29kZV9mbHVzaCgmZnNtKTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJcbiIpOwogICAgfQogICAgICAgIAp9CgoKaW50IG1haW4odm9pZCkgewogICAgRklMRSAqZnA7CiAgICBpZiggZm9wZW5fcygmZnAsImJhc2U2NHMuYyIsICJyYiIpIDwgMCkgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAi44OV44Kh44Kk44Or44KS6ZaL44GR44G+44Gb44KT44Gn44GX44GfIVxuIik7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICBiNjRlbmMoZnApOwogICAgZmNsb3NlKGZwKTsKICAgIHJldHVybiAwOwp9Ci8v