⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 md5.xs

📁 source of perl for linux application,
💻 XS
📖 第 1 页 / 共 2 页
字号:
    } while (--blocks);    ctx->A = A;    ctx->B = B;    ctx->C = C;    ctx->D = D;}#ifdef MD5_DEBUGstatic char*ctx_dump(MD5_CTX* ctx){    static char buf[1024];    sprintf(buf, "{A=%x,B=%x,C=%x,D=%x,%d,%d(%d)}",	    ctx->A, ctx->B, ctx->C, ctx->D,	    ctx->bytes_low, ctx->bytes_high, (ctx->bytes_low&0x3F));    return buf;}#endifstatic voidMD5Update(MD5_CTX* ctx, const U8* buf, STRLEN len){    STRLEN blocks;    STRLEN fill = ctx->bytes_low & 0x3F;#ifdef MD5_DEBUG      static int ucount = 0;    fprintf(stderr,"%5i: Update(%s, %p, %d)\n", ++ucount, ctx_dump(ctx),	                                        buf, len);#endif    ctx->bytes_low += len;    if (ctx->bytes_low < len) /* wrap around */	ctx->bytes_high++;    if (fill) {	STRLEN missing = 64 - fill;	if (len < missing) {	    Copy(buf, ctx->buffer + fill, len, U8);	    return;	}	Copy(buf, ctx->buffer + fill, missing, U8);	MD5Transform(ctx, ctx->buffer, 1);	buf += missing;	len -= missing;    }    blocks = len >> 6;    if (blocks)	MD5Transform(ctx, buf, blocks);    if ( (len &= 0x3F)) {	Copy(buf + (blocks << 6), ctx->buffer, len, U8);    }}static voidMD5Final(U8* digest, MD5_CTX *ctx){    STRLEN fill = ctx->bytes_low & 0x3F;    STRLEN padlen = (fill < 56 ? 56 : 120) - fill;    U32 bits_low, bits_high;#ifdef MD5_DEBUG    fprintf(stderr,"       Final:  %s\n", ctx_dump(ctx));#endif    Copy(PADDING, ctx->buffer + fill, padlen, U8);    fill += padlen;    bits_low = ctx->bytes_low << 3;    bits_high = (ctx->bytes_high << 3) | (ctx->bytes_low  >> 29);#ifdef BYTESWAP    *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_low);    fill += 4;    *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_high);   fill += 4;#else    u2s(bits_low,  ctx->buffer + fill);   fill += 4;    u2s(bits_high, ctx->buffer + fill);   fill += 4;#endif    MD5Transform(ctx, ctx->buffer, fill >> 6);#ifdef MD5_DEBUG    fprintf(stderr,"       Result: %s\n", ctx_dump(ctx));#endif#ifdef BYTESWAP    *(U32*)digest = BYTESWAP(ctx->A);  digest += 4;    *(U32*)digest = BYTESWAP(ctx->B);  digest += 4;    *(U32*)digest = BYTESWAP(ctx->C);  digest += 4;    *(U32*)digest = BYTESWAP(ctx->D);#else    u2s(ctx->A, digest);    u2s(ctx->B, digest+4);    u2s(ctx->C, digest+8);    u2s(ctx->D, digest+12);#endif}#ifndef INT2PTR#define INT2PTR(any,d)	(any)(d)#endifstatic MD5_CTX* get_md5_ctx(pTHX_ SV* sv){    if (SvROK(sv)) {	sv = SvRV(sv);	if (SvIOK(sv)) {	    MD5_CTX* ctx = INT2PTR(MD5_CTX*, SvIV(sv));	    if (ctx && ctx->signature == MD5_CTX_SIGNATURE) {		return ctx;            }        }    }    croak("Not a reference to a Digest::MD5 object");    return (MD5_CTX*)0; /* some compilers insist on a return value */}static char* hex_16(const unsigned char* from, char* to){    static const char hexdigits[] = "0123456789abcdef";    const unsigned char *end = from + 16;    char *d = to;    while (from < end) {	*d++ = hexdigits[(*from >> 4)];	*d++ = hexdigits[(*from & 0x0F)];	from++;    }    *d = '\0';    return to;}static char* base64_16(const unsigned char* from, char* to){    static const char base64[] =	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";    const unsigned char *end = from + 16;    unsigned char c1, c2, c3;    char *d = to;    while (1) {	c1 = *from++;	*d++ = base64[c1>>2];	if (from == end) {	    *d++ = base64[(c1 & 0x3) << 4];	    break;	}	c2 = *from++;	c3 = *from++;	*d++ = base64[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];	*d++ = base64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];	*d++ = base64[c3 & 0x3F];    }    *d = '\0';    return to;}/* Formats */#define F_BIN 0#define F_HEX 1#define F_B64 2static SV* make_mortal_sv(pTHX_ const unsigned char *src, int type){    STRLEN len;    char result[33];    char *ret;        switch (type) {    case F_BIN:	ret = (char*)src;	len = 16;	break;    case F_HEX:	ret = hex_16(src, result);	len = 32;	break;    case F_B64:	ret = base64_16(src, result);	len = 22;	break;    default:	croak("Bad convertion type (%d)", type);	break;    }    return sv_2mortal(newSVpv(ret,len));}/********************************************************************/typedef PerlIO* InputStream;MODULE = Digest::MD5		PACKAGE = Digest::MD5PROTOTYPES: DISABLEvoidnew(xclass)	SV* xclass    PREINIT:	MD5_CTX* context;    PPCODE:	if (!SvROK(xclass)) {	    STRLEN my_na;	    char *sclass = SvPV(xclass, my_na);	    New(55, context, 1, MD5_CTX);	    context->signature = MD5_CTX_SIGNATURE;	    ST(0) = sv_newmortal();	    sv_setref_pv(ST(0), sclass, (void*)context);	    SvREADONLY_on(SvRV(ST(0)));	} else {	    context = get_md5_ctx(aTHX_ xclass);	}        MD5Init(context);	XSRETURN(1);voidclone(self)	SV* self    PREINIT:	MD5_CTX* cont = get_md5_ctx(aTHX_ self);	const char *myname = sv_reftype(SvRV(self),TRUE);	MD5_CTX* context;    PPCODE:	New(55, context, 1, MD5_CTX);	ST(0) = sv_newmortal();	sv_setref_pv(ST(0), myname , (void*)context);	SvREADONLY_on(SvRV(ST(0)));	memcpy(context,cont,sizeof(MD5_CTX));	XSRETURN(1);voidDESTROY(context)	MD5_CTX* context    CODE:        Safefree(context);voidadd(self, ...)	SV* self    PREINIT:	MD5_CTX* context = get_md5_ctx(aTHX_ self);	int i;	unsigned char *data;	STRLEN len;    PPCODE:	for (i = 1; i < items; i++) {	    data = (unsigned char *)(SvPVbyte(ST(i), len));	    MD5Update(context, data, len);	}	XSRETURN(1);  /* self */voidaddfile(self, fh)	SV* self	InputStream fh    PREINIT:	MD5_CTX* context = get_md5_ctx(aTHX_ self);	STRLEN fill = context->bytes_low & 0x3F;#ifdef USE_HEAP_INSTEAD_OF_STACK	unsigned char* buffer;#else	unsigned char buffer[4096];#endif	int  n;    CODE:	if (fh) {#ifdef USE_HEAP_INSTEAD_OF_STACK	    New(0, buffer, 4096, unsigned char);	    assert(buffer);#endif            if (fill) {	        /* The MD5Update() function is faster if it can work with	         * complete blocks.  This will fill up any buffered block	         * first.	         */	        STRLEN missing = 64 - fill;	        if ( (n = PerlIO_read(fh, buffer, missing)) > 0)	 	    MD5Update(context, buffer, n);	        else		    XSRETURN(1);  /* self */	    }	    /* Process blocks until EOF or error */            while ( (n = PerlIO_read(fh, buffer, sizeof(buffer))) > 0) {	        MD5Update(context, buffer, n);	    }#ifdef USE_HEAP_INSTEAD_OF_STACK	    Safefree(buffer);#endif	    if (PerlIO_error(fh)) {		croak("Reading from filehandle failed");	    }	}	else {	    croak("No filehandle passed");	}	XSRETURN(1);  /* self */voiddigest(context)	MD5_CTX* context    ALIAS:	Digest::MD5::digest    = F_BIN	Digest::MD5::hexdigest = F_HEX	Digest::MD5::b64digest = F_B64    PREINIT:	unsigned char digeststr[16];    PPCODE:        MD5Final(digeststr, context);	MD5Init(context);  /* In case it is reused */        ST(0) = make_mortal_sv(aTHX_ digeststr, ix);        XSRETURN(1);voidmd5(...)    ALIAS:	Digest::MD5::md5        = F_BIN	Digest::MD5::md5_hex    = F_HEX	Digest::MD5::md5_base64 = F_B64    PREINIT:	MD5_CTX ctx;	int i;	unsigned char *data;        STRLEN len;	unsigned char digeststr[16];    PPCODE:	MD5Init(&ctx);	if (DOWARN) {            char *msg = 0;	    if (items == 1) {		if (SvROK(ST(0))) {                    SV* sv = SvRV(ST(0));		    if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))		        msg = "probably called as method";		    else			msg = "called with reference argument";		}	    }	    else if (items > 1) {		data = (unsigned char *)SvPVbyte(ST(0), len);		if (len == 11 && memEQ("Digest::MD5", data, 11)) {		    msg = "probably called as class method";		}	    }	    if (msg) {	        const char *f = (ix == F_BIN) ? "md5" :		                (ix == F_HEX) ? "md5_hex" : "md5_base64";	        warn("&Digest::MD5::%s function %s", f, msg);	    }	}	for (i = 0; i < items; i++) {	    data = (unsigned char *)(SvPVbyte(ST(i), len));	    MD5Update(&ctx, data, len);	}	MD5Final(digeststr, &ctx);        ST(0) = make_mortal_sv(aTHX_ digeststr, ix);        XSRETURN(1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -