Frage

Dank PBOs Hilfe und ihr Programm (veröffentlicht hier , für XORing eine große Datei), habe ich einige Tests durchgeführt, und ich sehe, dass ich ein anderes Problem:. die Maske durch eine anderen von 128-Bit, kein Standardtyp so groß wie benötigt wird, ist es geändert hat

Ich denke, eine Lösung kann eine Bibliothek enthalten sein, um verfügbare Integer-Typen zu erhöhen ... sondern dass ich es vorziehen, die jeweils 128 Bit Werte wie Strings zu interpretieren. Ist dies möglich, ohne Leistung zu verlieren?

Hier ist das aktuelle Programm (mit dem Bug „Integer-Konstante ist zu groß für seinen Typen“):

#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;
}

Dank für Ihre Anregungen.

Doug

War es hilfreich?

Lösung

Sie gehen zu müssen, Ihre Maske in Stücke als auch brechen.

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

Sie müssen dann mit dem Puffer Sie als eine Reihe eher dann Zeichen von unsigned int lesen arbeiten und die Brocken gegen das entsprechende Stück des Maskes xor:

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

Schließlich, je nach den Besonderheiten Ihrer Aufgabe, müssen Sie möglicherweise mit Endian Probleme mit dem Daten, die Sie lesen in der Datei behandeln.

Andere Tipps

Maske sogar „Brocken“ mit der ersten Hälfte der konstanten und ungeradeen „Brocken“ mit der anderen Hälfte.

/* ... */
unsigned int xormask[2] = {0xA37c54f173f02889, 0xa64be02f2bc44112};
/* ... */
        for(i = 0;i < end; ++i)
        {
                ((unsigned int *)buffer)[i] ^= xormask[i & 1];
        }
/* ... */

Gehen Sie durch Ihren Schlüssel und Klartextbyte-für-Byte und führt die XOR auf jedes Byte getrennt.

Ändern Sie Schlüssel ein Array von Bytes zu sein und einen Zeiger auf das Array für die Bequemlichkeit bei der Verwendung der Schlüssel erstellen:

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

char const* pKeyByte = key;

Dann ändern Sie die Zeile, wo Sie von

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

zu:

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

Jetzt können Sie BLOCKSIZE ändern, was auch immer Sie Ihre I / O-Größe sein mögen, unabhängig von der Schlüssellänge. Beachten Sie, dass, wie Sie verwenden es, BLOCKSIZE die Anzahl von Bytes definiert in jeder Schleife aus der Datei eingelesen werden -. Es ist nicht die Anzahl der Bits im Schlüssel

Beachten Sie, dass die Einsprüche über XOR-Verschlüsselung ich gepostet in Ihrer letzten Frage gilt nach wie vor.

Nicht alle (viele?) Plattformen werden 128-Bit-Integer unterstützen. Sie könnten den Code ausklammern, die direkt mit den 128-Bit-Zahlen und schreiben zwei Versionen davon, ein für Plattformen beschäftigt, die 128-Bit-Zahlen und ein anderes für diejenigen unterstützen, die nicht tun. Ein Konfigurationsskript für 128-Bit-Unterstützung überprüfen kann (Check „sizeof(long long)“ und für „uint128_t“ vielleicht?) Und wählen Sie zwischen den beiden Implementierungen.

Basierend auf Burr 's Antwort, ich würde das lieber:

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

setzt die Innenschleife, dass Ihre bei 16 Bytes ausgerichtet ist (das heißt buffer[i + j] prüft nicht für die tatsächliche Länge des Puffers).

Die Größen der Integer-Typen sind ein Kern Sprache charakteristisch. Es kann nicht, indem alle Bibliotheken geändert werden. Wenn Sie darauf bestehen, den Einbau-Integral-Typs zur Verwendung, die einzige Möglichkeit, zu überwinden ths limitition auf einem andere Implementierung zu wechseln ist, die native größeren Integer-Typ im Kern Sprachniveau unterstützt.

Sonst werden Sie haben entweder explizit teilen Sie Ihre „lang“ konstant in zwei oder mehr „kürzer“ Konstanten, oder eine Bibliothek verwenden, die genau das gleiche tun werden „unter der Haube“.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top