예제 #1
0
파일: digest.c 프로젝트: rforge/digest
SEXP digest(SEXP Txt, SEXP Algo, SEXP Length, SEXP Skip, SEXP Leave_raw) {
  FILE *fp=0;
  char *txt;
  int algo = INTEGER_VALUE(Algo);
  int  length = INTEGER_VALUE(Length);
  int skip = INTEGER_VALUE(Skip);
  int leaveRaw = INTEGER_VALUE(Leave_raw);
  SEXP result = NULL;
  char output[128+1], *outputp = output;    /* 33 for md5, 41 for sha1, 65 for sha256, 128 for sha512; plus trailing NULL */
  int nChar;
  int output_length = -1;
  if (IS_RAW(Txt)) { /* Txt is either RAW */
    txt = (char*) RAW(Txt);
    nChar = LENGTH(Txt);
  } else { /* or a string */
    txt = (char*) STRING_VALUE(Txt);
    nChar = strlen(txt);
  }
  if (skip>0) {
    if (skip>=nChar) nChar=0;
    else {
      nChar -= skip;
      txt += skip;
    }
  }
  if (length>=0 && length<nChar) nChar = length;
  
  switch (algo) {
  case 1: {     /* md5 case */
    md5_context ctx;
    output_length = 16;
    unsigned char md5sum[16];
    int j;
    md5_starts( &ctx );
    md5_update( &ctx, (uint8 *) txt, nChar);
    md5_finish( &ctx, md5sum );
    memcpy(output, md5sum, 16);

    if (!leaveRaw)
      for(j = 0; j < 16; j++) 
        sprintf(output + j * 2, "%02x", md5sum[j]);
        
    break;
  }
  case 2: {     /* sha1 case */
    int j;
    sha1_context ctx;
    output_length = 20;
    unsigned char sha1sum[20];

    sha1_starts( &ctx );
    sha1_update( &ctx, (uint8 *) txt, nChar);
    sha1_finish( &ctx, sha1sum );
    memcpy(output, sha1sum, 20);

    if (!leaveRaw)
      for( j = 0; j < 20; j++ ) 
        sprintf( output + j * 2, "%02x", sha1sum[j] );

    break;
  }
  case 3: {     /* crc32 case */
    unsigned long val, l;
    l = nChar;

    val  = digest_crc32(0L, 0, 0);
    val  = digest_crc32(val, (unsigned char*) txt, (unsigned) l);
      
    sprintf(output, "%2.2x", (unsigned int) val);

    break;
  }
  case 4: {     /* sha256 case */
    int j;
    sha256_context ctx;
    output_length = 32;
    unsigned char sha256sum[32];

    sha256_starts( &ctx );
    sha256_update( &ctx, (uint8 *) txt, nChar);
    sha256_finish( &ctx, sha256sum );
    memcpy(output, sha256sum, 32);

    if(!leaveRaw)
      for( j = 0; j < 32; j++ ) 
        sprintf( output + j * 2, "%02x", sha256sum[j] );

    break;
  }
  case 5: {     /* sha2-512 case */
    int j;
    SHA512_CTX ctx;
    output_length = SHA512_DIGEST_LENGTH;
    uint8_t sha512sum[output_length], *d = sha512sum;

    SHA512_Init(&ctx);
    SHA512_Update(&ctx, (uint8 *) txt, nChar);
    // Calling SHA512_Final, because SHA512_End will already
    // convert the hash to a string, and we also want RAW
    SHA512_Final(sha512sum, &ctx);
    memcpy(output, sha512sum, output_length);

    // adapted from SHA512_End
    if(!leaveRaw) {
      for (j = 0; j < output_length; j++) {
        *outputp++ = sha2_hex_digits[(*d & 0xf0) >> 4];
        *outputp++ = sha2_hex_digits[*d & 0x0f];
        d++;
      }
      *outputp = (char)0;
    }
    break;
  }
  case 101: {     /* md5 file case */
    int j;
    md5_context ctx;
    output_length = 16;
    unsigned char buf[1024];
    unsigned char md5sum[16];

    if (!(fp = fopen(txt,"rb"))) {
      error("Cannot open input file: %s", txt);
      return(NULL);
    }
    if (skip > 0) fseek(fp, skip, SEEK_SET);
    md5_starts( &ctx );
    if (length>=0) {  
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 
             && length>0) {
        if (nChar>length) nChar=length;
        md5_update( &ctx, buf, nChar );
        length -= nChar;
      }
    } else {
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) 
        md5_update( &ctx, buf, nChar );
    }
    fclose(fp);
    md5_finish( &ctx, md5sum );
    memcpy(output, md5sum, 16);
    if (!leaveRaw)
      for(j = 0; j < 16; j++) 
        sprintf(output + j * 2, "%02x", md5sum[j]);
    break;
  }
  case 102: {     /* sha1 file case */
    int j;
    sha1_context ctx;
    output_length = 20;
    unsigned char buf[1024];
    unsigned char sha1sum[20];
      
    if (!(fp = fopen(txt,"rb"))) {
      error("Cannot open input file: %s", txt);
      return(NULL);
    }
    if (skip > 0) fseek(fp, skip, SEEK_SET);
    sha1_starts ( &ctx );
    if (length>=0) {  
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 
             && length>0) {
        if (nChar>length) nChar=length;
        sha1_update( &ctx, buf, nChar );
        length -= nChar;
      }
    } else {
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) 
        sha1_update( &ctx, buf, nChar );
    }
    fclose(fp);
    sha1_finish ( &ctx, sha1sum );
    memcpy(output, sha1sum, 20);
    if(!leaveRaw)
      for( j = 0; j < 20; j++ ) 
        sprintf( output + j * 2, "%02x", sha1sum[j] );
    break;
  }
  case 103: {     /* crc32 file case */
    unsigned char buf[1024];
    unsigned long val;
      
    if (!(fp = fopen(txt,"rb"))) {
      error("Cannot open input file: %s", txt);
      return(NULL);
    }
    if (skip > 0) fseek(fp, skip, SEEK_SET);
    val  = digest_crc32(0L, 0, 0);
    if (length>=0) {  
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 
             && length>0) {
        if (nChar>length) nChar=length;
        val  = digest_crc32(val , buf, (unsigned) nChar);
        length -= nChar;
      }
    } else {
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) 
        val  = digest_crc32(val , buf, (unsigned) nChar);
    }
    fclose(fp);      
    sprintf(output, "%2.2x", (unsigned int) val);
    break;
  }
  case 104: {     /* sha256 file case */
    int j;
    sha256_context ctx;
    output_length = 32;
    unsigned char buf[1024];
    unsigned char sha256sum[32];
      
    if (!(fp = fopen(txt,"rb"))) {
      error("Cannot open input file: %s", txt);
      return(NULL);
    }
    if (skip > 0) fseek(fp, skip, SEEK_SET);
    sha256_starts ( &ctx );
    if (length>=0) {  
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 
             && length>0) {
        if (nChar>length) nChar=length;
        sha256_update( &ctx, buf, nChar );
        length -= nChar;
      }
    } else {
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) 
        sha256_update( &ctx, buf, nChar );
    }
    fclose(fp);
    sha256_finish ( &ctx, sha256sum );
    memcpy(output, sha256sum, 32);
    if(!leaveRaw)
      for( j = 0; j < 32; j++ ) 
        sprintf( output + j * 2, "%02x", sha256sum[j] );
    break;
  }
  case 105: {     /* sha2-512 file case */
    int j;
    SHA512_CTX ctx;
    output_length = SHA512_DIGEST_LENGTH;
    uint8_t sha512sum[output_length], *d = sha512sum;

    unsigned char buf[1024];

    if (!(fp = fopen(txt,"rb"))) {
      error("Cannot open input file: %s", txt);
      return(NULL);
    }
    if (skip > 0) fseek(fp, skip, SEEK_SET);
    SHA512_Init(&ctx);
    if (length>=0) {
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0
             && length>0) {
        if (nChar>length) nChar=length;
        SHA512_Update( &ctx, buf, nChar );
        length -= nChar;
      }
    } else {
      while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0)
        SHA512_Update( &ctx, buf, nChar );
    }
    fclose(fp);

		// Calling SHA512_Final, because SHA512_End will already
		// convert the hash to a string, and we also want RAW
		SHA512_Final(sha512sum, &ctx);
		memcpy(output, sha512sum, output_length);

		// adapted from SHA512_End
		if(!leaveRaw) {
		  for (j = 0; j < output_length; j++) {
        *outputp++ = sha2_hex_digits[(*d & 0xf0) >> 4];
        *outputp++ = sha2_hex_digits[*d & 0x0f];
        d++;
		  }
            *outputp = (char)0;

		}
    break;
  }

  default: {
    error("Unsupported algorithm code");
    return(NULL);
  }  
  }

  if (leaveRaw && output_length > 0) {
    PROTECT(result=allocVector(RAWSXP, output_length));
    memcpy(RAW(result), output, output_length);
  } else {
    PROTECT(result=allocVector(STRSXP, 1));
    SET_STRING_ELT(result, 0, mkChar(output));
  }
  UNPROTECT(1);

  return result;
}
예제 #2
0
파일: digest_C.c 프로젝트: cran/SoDA
static char * digest_string(
			   char *txt,
			   int algo,
			   int  length,
			   char *output) {
  FILE *fp=0;
  error_message = NULL;
  int nChar = strlen(txt);
  if (length>=0 && length<nChar) nChar = length;
  
  switch (algo) {
    case 1: {			/* md5 case */
      md5_context ctx;
      unsigned char md5sum[16];
      int j;

      md5_starts( &ctx );
      md5_update( &ctx, (uint8 *) txt, nChar);
      md5_finish( &ctx, md5sum );

      for(j = 0; j < 16; j++) {
	sprintf(output + j * 2, "%02x", md5sum[j]);
      }
      break;
    }
    case 2: {			/* sha1 case */
      int j;
      sha1_context ctx;
      unsigned char sha1sum[20];

      sha1_starts( &ctx );
      sha1_update( &ctx, (uint8 *) txt, nChar);
      sha1_finish( &ctx, sha1sum );

      for( j = 0; j < 20; j++ ) {
	sprintf( output + j * 2, "%02x", sha1sum[j] );
      }
      break;
    }
    case 3: {			/* crc32 case */
      unsigned long val, l;
      l = nChar;

      val  = digest_crc32(0L, 0, 0);
      val  = digest_crc32(val, (unsigned char*) txt, (unsigned) l);
      
      sprintf(output, "%2.2x", (unsigned int) val);

      break;
    }
    case 101: {			/* md5 file case */
      int j;
      md5_context ctx;
      unsigned char buf[1024];
      unsigned char md5sum[16];

      if (!(fp = fopen(txt,"rb"))) {
        error_message = (strcat("Can not open input file: ", txt));    
        return (char *)NULL;
      }
      md5_starts( &ctx );
      if (length>=0) {  
        while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 
	       && length>0) {
          if (nChar>length) nChar=length;
          md5_update( &ctx, buf, nChar );
          length -= nChar;
        }
      } else {
        while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) 
          md5_update( &ctx, buf, nChar );
      }
      fclose(fp);
      md5_finish( &ctx, md5sum );
      for(j = 0; j < 16; j++) sprintf(output + j * 2, "%02x", md5sum[j]);
      break;
    }
    case 102: {			/* sha1 file case */
      int j;
      sha1_context ctx;
      unsigned char buf[1024];
      unsigned char sha1sum[20];
      
      if (!(fp = fopen(txt,"rb"))) {
        error_message = (strcat("Can not open input file: ", txt));    
        return (char *)NULL;
      }
      sha1_starts ( &ctx );
      if (length>=0) {  
        while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 
	       && length>0) {
          if (nChar>length) nChar=length;
          sha1_update( &ctx, buf, nChar );
          length -= nChar;
        }
      } else {
        while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) 
          sha1_update( &ctx, buf, nChar );
      }
      fclose(fp);
      sha1_finish ( &ctx, sha1sum );
      for( j = 0; j < 20; j++ ) sprintf( output + j * 2, "%02x", sha1sum[j] );
      break;
    }
    case 103: {			/* crc32 file case */
      unsigned char buf[1024];
      unsigned long val;
      
      if (!(fp = fopen(txt,"rb"))) {
        error_message = (strcat("Can not open input file: ", txt));    
        return (char *)NULL;
      }
      val  = digest_crc32(0L, 0, 0);
      if (length>=0) {  
        while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 
	       && length>0) {
          if (nChar>length) nChar=length;
          val  = digest_crc32(val , buf, (unsigned) nChar);
          length -= nChar;
        }
      } else {
        while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) 
          val  = digest_crc32(val , buf, (unsigned) nChar);
      }
      fclose(fp);      
      sprintf(output, "%2.2x", (unsigned int) val);
      break;
    }

    default: {
      error_message = ("Unsupported algorithm code");
      return (char *)NULL;
    }  
  }
    
  return output;

}