在c ++中压缩字符串在.Net中解压缩不起作用

时间:2013-10-18 08:19:32

标签: c++ .net string compression

我试图在c ++编码中压缩字符串并存储在Linux服务器的MYSQL varchar字段中,然后获取字符串然后在.Net中解压缩。我已经尝试了很多方法,但没有运气。请帮帮我。

这是我的c ++代码。

#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <openssl/evp.h>
#include "zlib.h"
#include "base64.cpp"
using namespace std;

#define AES_BLOCK_SIZE 256

int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx,
             EVP_CIPHER_CTX *d_ctx)
{
  int i, nrounds = 5;
  unsigned char key[32], iv[32];

  /*
   * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material.
   * nrounds is the number of times the we hash the material. More rounds are more secure but
   * slower.
   */
  i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv);
  if (i != 32) {
    printf("Key size is %d bits - should be 256 bits\n", i);
    return -1;
  }

  EVP_CIPHER_CTX_init(e_ctx);
  EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
  EVP_CIPHER_CTX_init(d_ctx);
  EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);

  return 0;
}

unsigned char *aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, int *len)
{
  /* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes */
  int c_len = *len + AES_BLOCK_SIZE - 1, f_len = 0;
  unsigned char *ciphertext = (unsigned char *)malloc(c_len);

  /* allows reusing of 'e' for multiple encryption cycles */
  if(!EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL)){
    printf("ERROR in EVP_EncryptInit_ex \n");
    return NULL;
  }

  /* update ciphertext, c_len is filled with the length of ciphertext generated,
    *len is the size of plaintext in bytes */
  if(!EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len)){
    printf("ERROR in EVP_EncryptUpdate \n");
    return NULL;
  }

  /* update ciphertext with the final remaining bytes */
  if(!EVP_EncryptFinal_ex(e, ciphertext+c_len, &f_len)){
    printf("ERROR in EVP_EncryptFinal_ex \n");
    return NULL;
  }

  *len = c_len + f_len;
  return ciphertext;
}

std::string string_compress(std::string const& s) {

    unsigned int sourceSize = s.size(); 
    const char * source = s.c_str();

    unsigned long dsize = sourceSize + (sourceSize * 0.1f) + 16;
    char * destination = new char[dsize];

    int result = compress((unsigned char *)destination, &dsize, (const unsigned char *)source, sourceSize);

    if(result != Z_OK)
        std::cout << "Compress error occured! Error code: " << result << std::endl; 

    return destination;
}
int main (int argc, char * const argv[]) {


    std::string to_compress = "1^52^1^52,2^57^52^109,3^6^109^115";
    std::string compressed = string_compress(to_compress);

    /* "opaque" encryption, decryption ctx structures that libcrypto uses to record
     status of enc/dec operations */
    EVP_CIPHER_CTX en, de;

    /* The salt paramter is used as a salt in the derivation: it should point to an 8 byte buffer or NULL if no salt is used. */
    unsigned char salt[] = {1,2,3,4,5,6,7,8};

    unsigned char *key_data;
    int key_data_len, i;

    char *input;
    input = new char[compressed.size()+1];
    std::copy(compressed.begin(), compressed.end(), input);

    /* the key_data is read from the argument list */
    key_data = (unsigned char *)"X";
    key_data_len = 1;

    /* gen key and iv. init the cipher ctx object */
    if (aes_init(key_data, key_data_len, salt, &en, &de)) {
        printf("Couldn't initialize AES cipher\n");
        return -1;
    }

    unsigned char *ciphertext;
    int olen, len;

    /* The enc/dec functions deal with binary data and not C strings. strlen() will
       return length of the string without counting the '\0' string marker. We always
       pass in the marker byte to the encrypt/decrypt functions so that after decryption
       we end up with a legal C string */
    olen = len = strlen(input)+1;

    ciphertext = aes_encrypt(&en, (unsigned char *)input, &len);

    std::string encodedData = base64_encode(ciphertext, len);

    std::string query="update cac001_000001a set datap=" + TOSQL(encodedData) + " where category_id=1 and cache_key_id=1";

    objcache.Save(query);

    free(ciphertext);
    EVP_CIPHER_CTX_cleanup(&de);
    EVP_CIPHER_CTX_cleanup(&en);

    return 0;
}

这是我的.Net代码

Public Sub Decompress()
    Dim strComp As String
    Dim strDecomp As String

    Dim salt As Byte() = {1, 2, 3, 4, 5, 6, 7, 8}
    Dim keyBytes As Byte() = New Byte() {243, 203, 30, 241, 23, 196, 12, 54, 35, 77, 92, 17, 170, 34, 235, 42, 75, 52, 118, 3, 64, 84, 203, 40, 1, 68, 83, 16, 206, 147, 126, 48}
    Dim VectorBytes As Byte() = New Byte() {100, 56, 168, 166, 119, 82, 215, 80, 85, 81, 209, 120, 205, 124, 157, 172, 208, 252, 38, 89, 255, 127, 0, 0, 21, 71, 225, 196, 50, 0, 0, 0}

    strComp = Decrypt(strComp, keyBytes, VectorBytes)

    strDecomp = clsZlib.BytesToString(clsZlib.Decompress(clsZlib.StringToBytes(strComp)))
End Sub


Public Function Decrypt(ByVal Text As String, ByVal keyBytes As Byte(), ByVal VectorBytes As Byte()) As String
    Try
      Dim TextBytes As Byte() = Convert.FromBase64String(Text)
      Dim rijKey As New RijndaelManaged()
      rijKey.BlockSize = 256
      'rijKey.IV = VectorBytes
      rijKey.Mode = CipherMode.CBC
      Dim decryptor As ICryptoTransform = rijKey.CreateDecryptor(keyBytes, VectorBytes)
      Dim memoryStream As New MemoryStream(TextBytes)
      Dim cryptoStream As New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
      Dim pTextBytes As Byte() = New Byte(TextBytes.Length - 1) {}
      Dim decryptedByteCount As Integer '= cryptoStream.Read(pTextBytes, 0, pTextBytes.Length)

      While ((decryptedByteCount = cryptoStream.Read(pTextBytes, 0, pTextBytes.Length)) > 0)

      End While

      memoryStream.Close()
      cryptoStream.Close()
      Dim plainText As String = Encoding.UTF8.GetString(pTextBytes, 0, decryptedByteCount)
      Return plainText
    Catch a As Exception
      Response.Write("Falsches Passwort " + a.Message)
      Dim t As String = ""
      Return t
    End Try
End Function


Public Class clsZlib

      <DllImport("zlib.DLL", EntryPoint:="compress")> _
    Private Shared Function ZCompress(ByVal dest As Byte(), ByRef destLen As Integer, ByVal src As Byte(), ByVal srcLen As Integer) As Integer
        ' Leave function empty - DLLImport attribute forwards calls to CompressByteArray to compress in zlib.dLL
      End Function
      <DllImport("zlib.DLL", EntryPoint:="uncompress")> _
      Private Shared Function ZUncompress(ByVal dest As Byte(), ByRef destLen As Integer, ByVal src As Byte(), ByVal srcLen As Integer) As Integer
        ' Leave function empty - DLLImport attribute forwards calls to UnCompressByteArray to Uncompress in zlib.dLL
      End Function

      Public Shared Function BytesToString(ByVal bytes() As Byte) As String
        Return Encoding.UTF8.GetString(bytes)
      End Function
      Public Shared Function BytesToString(ByVal bytes() As Byte, ByVal index As Integer, ByVal count As Integer) As String
        If bytes.Length < count Then count = bytes.Length
        Return Encoding.UTF8.GetString(bytes, index, count)
        'Return Encoding.GetEncoding(1256).GetString(bytes, index, count)
      End Function
      Public Shared Function StringToBytes(ByVal s As String) As Byte()
        Return Encoding.UTF8.GetBytes(s)
      End Function

      Public Shared Function Decompress(ByVal Data() As Byte) As Byte()
    'DeCompresses Data into a temp buffer..note that Origsize must be the size of the original data before compression
    'Returns compressed Data in Data if TempBuff not specified
    'Returns Result = Size of decompressed data if ok, -1 if not
    'Allocate memory for buffers
    'If Data.Length < 23 Then Return Data
    Try
      Dim result As Integer
      Dim Origsize As Short = (Data(0) * &H100 Or Data(1))

      Dim TempBuffer(UBound(Data) - 3) As Byte
      'Decompress data
      Buffer.BlockCopy(Data, 2, TempBuffer, 0, UBound(Data) - 2)

      ReDim Data(Origsize - 1)
      result = ZUncompress(Data, Origsize, TempBuffer, UBound(TempBuffer) + 1)

      TempBuffer = Nothing
      Return Data
    Catch ex As Exception
      Return Data
    End Try
  End Function

End Class

请帮帮我。

0 个答案:

没有答案