0

pbos ヘルプとそのプログラム (大きなファイルを xor 処理するためにここで公開) のおかげで、いくつかのテストを実行したところ、別の問題があることがわかりました。必要に応じて。

解決策は、利用可能な整数型を増やすライブラリを含めることだと思います...しかし、文字列などの各128ビット値を解釈することを好みます。これはパフォーマンスを失うことなく可能ですか?

これが現在のプログラムです(「整数定数がその型に対して大きすぎます」というバグがあります):

#include <stdio.h>
#include <stdlib.h>

#define BLOCKSIZE 128
#define MASK 0xA37c54f173f02889a64be02f2bc44112 /* a 128 bits constant */

void
usage(const char *cmd)
{
    fprintf(stderr, "Usage: %s <in-file> [<out-file>]\n", cmd);
    exit (EXIT_FAILURE);
}

int
main(int argc, char *argv[])
{
  if (argc < 3) usage(argv[0]);

  FILE *in = fopen(argv[1], "rb");

  if (in == NULL)
  {
    printf("Cannot open: %s", argv[2]);
    return EXIT_FAILURE;
  }

  FILE *out = fopen(argv[2], "wb");

  if (out == NULL)
  {
    fclose(in);
    printf("Unable to open '%s' for writing.", argv[2]);
  }

  char buffer[BLOCKSIZE];
  int count;

  while (count = fread(buffer, 1, BLOCKSIZE, in))
  {
    int i;
    for (i = 0; i < count; i++)
    {
      ((unsigned long *)buffer)[i] ^= MASK; /* this line is bugged */
    }

    if (fwrite(buffer, 1, count, out) != count)
    {
      fclose(in);
      fclose(out);
      printf("Cannot write, disk full?\n");
      return EXIT_FAILURE;
    }
  }

  fclose(in);
  fclose(out);

  return EXIT_SUCCESS;
}

提案をありがとう。

ダグ

4

6 に答える 6

2

キーとプレーンテキストをバイトごとにウォークスルーし、各バイトで個別にXORを実行します。

キーをバイトの配列に変更し、キーの使用に便利なようにその配列へのポインターを作成します。

char const key[] = {
    0xA3, 0x7c, 0x54, 0xf1, 
    0x73, 0xf0, 0x28, 0x89, 
    0xa6, 0x4b, 0xe0, 0x2f, 
    0x2b, 0xc4, 0x41, 0x12
};

char const* pKeyByte = key;

次に、暗号化元の行を変更します

((unsigned long *)buffer)[i] ^= MASK; /* this line is bugged */

に:

buffer[i] ^= *pKeyByte++;
if (pKeyByte == (key + sizeof(key))) {
    /* wrap to start of key */
    pKeyByte = key;
}

BLOCKSIZEこれで、キーの長さに関係なく、I/Oサイズを自由に変更できます。BLOCKSIZE使用しているときに、各ループでファイルから読み込まれるバイト数を定義することに注意してください。これは、キーのビット数ではありません。

前回の質問で投稿したXOR暗号化に関する警告が引き続き適用されることに注意してください。

于 2009-11-01T16:32:33.500 に答える
2

一定の「チャンク」の前半で偶数の「チャンク」をマスクし、残りの半分で奇数の「チャンク」をマスクします。

/* ... */
unsigned int xormask[2] = {0xA37c54f173f02889, 0xa64be02f2bc44112};
/* ... */
        for(i = 0;i < end; ++i)
        {
                ((unsigned int *)buffer)[i] ^= xormask[i & 1];
        }
/* ... */
于 2009-11-01T16:28:50.090 に答える
1

すべての(多くの?)プラットフォームが128ビット整数をサポートするわけではありません。128ビットの数値を直接処理するコードを除外し、その2つのバージョンを作成できます。1つは128ビットの数値をサポートするプラットフォーム用で、もう1つはサポートしないプラットフォーム用です。構成スクリプトは、128ビットのサポートをチェックし(「sizeof(long long)」と「」をチェックしuint128_tますか?)、2つの実装のどちらかを選択できます。

于 2009-11-01T16:27:56.503 に答える
0

整数型のサイズは、コア言語の特性です。ライブラリを含めて変更することはできません。組み込みの整数型の使用を主張する場合、この制限を克服する唯一の方法は、コア言語レベルでより大きな整数型をネイティブにサポートする別の実装に切り替えることです。

それ以外の場合は、「長い」定数を2つ以上の「短い」定数に明示的に分割するか、「内部」でまったく同じことを行うライブラリを使用する必要があります。

于 2009-11-01T16:53:50.883 に答える
0

Burrの答えに基づいて、私はこれを好むでしょう:

int i;
int sizeOfKey = sizeof(key); // key is an array of chars
for (i = 0; i < count; i++)
{
    buffer[i] ^= key[i % sizeOfKey];
}

内側のループがあると、16バイトで整列されていると想定されます(つまりbuffer[i + j]、バッファの実際の長さはチェックされません)。

于 2009-11-01T16:41:14.557 に答える
0

マスクもチャンクに分割する必要があります。

unsigned int mask[] = { 0xA37c54f1, 0x73f02889, 0xa64be02f, 0x2bc44112 };
unsigned int mask_len = sizeof(mask) / sizeof(*mask);

次に、charsではなく一連のunsigned intとして読み込んだバッファを操作し、マスクの適切なチャンクに対してチャンクをxorする必要があります。

unsigned int *uint_buffer = (unsigned int *)buffer;
for (i = 0; i < count / sizeof(int); i++)
{
    uint_buffer[i] ^= mask[i % mask_len];
}

最後に、タスクの詳細によっては、ファイルから読み込んだデータのエンディアンの問題に対処する必要がある場合があります。

于 2009-11-01T16:28:58.717 に答える