Zeichenfolge (C-String) auf Mod 8/16 verlängern
-
Guten Tag !
Bin auf der Suche nach einer sehr schnellen Methode Zeichenfolgen zu verlängern. Das heißt für einen Verschlüsselungs-Algorithmus muss die Länge des Klartextes durch 8 bzw. 16 teilbar sein.
Folgendes theoretisches Konzept habe ich mir dazu überlegt:
1.) nächste durch 8/16 teilbare Zahl finden
2.) Puffer-Variable mit der "neuen Länge" anlegen
3.) alte Zeichenfolge in neue übertragen und mit 0 auffüllenDas Problem ist jetzt die praktische Umsetzung. Könnte mir jemand dabei wohl unter die Arme greifen ???
P.S.: Wüsste jemand eine andere/bessere Methode ???
Grüsse Michael
-
Hm, die Länge des Strings mit length bzw. getLength erfragen,
dann die 'Neue' Länge berechnen. Abstand zwischen denen ausrechnen,
ein char* array dieser Größe allokieren, und einem String zuweisen.
(Oder in einer Schleife jeweils ein char an den String anhängen ;))
neuerstring = textstring + 'array'string;Devil
-
Mein Code sieht jetzt wie folgt aus:
Eigene Kopier-Funktion für unsigned char Strings
inline void stringcopy (unsigned const char *sSource, unsigned char *sDest){ for ( ; *sSource != '\0'; ++sSource, ++sDest) { *sDest = *sSource; } *sDest = '\0'; }
Diese Funktion gibt die nächste Mod 8/16 Zahl zurück
inline WORD32 getmodbase(WORD32 lNumOfBytes, int base) { //Überprüfen ob String nicht durch 8 teilbar ist if (lNumOfBytes % base != 0) { while (lNumOfBytes % base != 0) { lNumOfBytes++; } // while } // if return lNumOfBytes; }
Die Funktion erledigt das Auffüllen
inline void pushstring (const unsigned char *sSrc, unsigned char *sDest, WORD32 lNullBytes) { // String kopieren stringcopy(sSrc, sDest); // Überprüfen ob nur mit einem Zeichen aufgefüllt werden muss if (lNullBytes == 1) { strcat((char *)sDest, "1"); } // if else if (lNullBytes > 1 ){ WORD32 len = lNullBytes; //- 1; strcat((char *) sDest, "1"); for (int i = 1; i < lNullBytes; i++) { strcat((char *) sDest, "0"); } } // else if }
Test der Routinen
#include <string.h> #include <iostream> using namespace std; typedef unsigned __int32 WORD32; // ***** P R O T O T Y P E S ***** // inline WORD32 getmodbase(WORD32 lNumOfBytes, int base=8); // gibt die nächste durch BASE (8/16) teilbare Zahl zurück inline void stringcopy (const unsigned char *sSource, unsigned char *sDest); // kopiert einen String (Pointer - Version) inline void pushstring (const unsigned char *sSrc, unsigned char *sDest, WORD32 lNullBytes); // füllt einen String mit NULLEN auf int main(void) { unsigned char sData[] = "Hallo Welt !"; int i = getmodbase(strlen((char *) sData)); int len = strlen((char *) sData); unsigned char *snew = new unsigned char[i+1]; pushstring(sData, snew, i - len); cout << "Verlaengerung nach: " << i << endl << "Original: " << sData << endl << "Kopie: " << snew << endl; return 0; }
Kann man diesen Code noch optimieren damit diese Routinen so schnell wie möglich ablaufen, denn eine Verschlüsselung nimmt ja auch Zeit in Ansrpuch.
Gruß Michael
-
Jep, einen Verbesserungsvorschlag hab ich da schon
inline WORD32 getmodbase(WORD32 lNumOfBytes, int base) { if(!(lNumOfBytes%base)) return lNumOfBytes; return lNumOfBytes + (base - (lNumOfBytes % base)); }
und
inline void pushstring (const unsigned char *sSrc, unsigned char *sDest, WORD32 lNullBytes) { int len = strlen((char*)sSrc); //String Kopieren memcpy((char*)sDest,(char*)sSrc,len); //ans Ende was anhängen if (lNullBytes){ sDest = (unsigned char*)(sSrc + len); *(sDest++)='1'; memset((char*)sDest, '0' ,lNullBytes-1); *(sDest+lNullBytes+1)='\0'; }
nebenbei bemerkt ist das hier alles Ansi-C und hat mit C++ nix am Hut (Außer Deine Ausgabe)
Und Du sollten in Deinen Funktionen zuerst das Ziel, und dann die Quelle in der Parameterliste angeben. Da das sonst alle machen, ist das weniger Verwirrend.
und, warum nimmst Du "unsigned char*", wenn Du doch jedesmal nach "char*" casten must?
grüße Con@n
-
in C++ Würde ich das so machen
inline void StringFill( std::string &String, int base=8) { int len = String.length(); static std::string temp; temp=""; if (len=( len % base)) { len = base - len ; temp.insert( temp.begin() , len , '0' ); temp[0] = '1'; String+=temp; } }
das füllt Dir einen String auf die Basis, die Du angibts auf.
grüße Con@n
-
Michael__W. schrieb:
inline void stringcopy (unsigned const char *sSource, unsigned char *sDest){ for ( ; *sSource != '\0'; ++sSource, ++sDest) { *sDest = *sSource; } *sDest = '\0'; }
Wahrscheinlich bringt dir folgendes zwar keine Geschwindigkeitsvorteile, aber mich beeindruckt trotzdem die Ausdruckskraft:
inline void stringcopy(const char* sSource, char* sDest) { while(*sDest++=*sSource++) ; }
Quelle: "Die C++ Programmiersprache" von Bjarne Stroustroup
-
@Con@n
Jep, einen Verbesserungsvorschlag hab ich da schon
Gut, das leuchtet ein und ist auch schneller.
Zu der veränderten PUSHSTRING Funktion habe ich zwei Verständnis-Fragen.
Mit memcpy verschiebt man Speicherblöcke ??? <- ist somit schneller als strcpyMit memset wird der String anhand von lNullBytes aufgefüllt. Wenn lNullBytes jetzt nur 1 wird aber nur eine 1 angehängt, richtig ?
in C++ Würde ich das so machen
Die Pointer Version ist aber schneller, richtig ?
mit in C++ Würde ich das so machen meinst du eine OOP Lösung durch die Klasse String, richtig ?
Herzlichen Dank für eure Hilfe !
Grüsse Michael
-
Michael__W. schrieb:
Zu der veränderten PUSHSTRING Funktion habe ich zwei Verständnis-Fragen.
Mit memcpy verschiebt man Speicherblöcke ??? <- ist somit schneller als strcpyJa, memcpy ist etwas schneller als strcpy, aber nicht wirklich entscheident
Michael__W. schrieb:
Mit memset wird der String anhand von lNullBytes aufgefüllt. Wenn lNullBytes jetzt nur 1 wird aber nur eine 1 angehängt, richtig ?
auch richtig, es wird die erste Stelle mit '1' überschrieben, und dann der Rest mit '0'. wenn es keinen Rest gibt, dann passiert nix.
Michael__W. schrieb:
Die Pointer Version ist aber schneller, richtig ?
ähmm, nein. In meinen Test hat die C++ Variante besser abgeschnitten. Vor allem, wenn die Zeichenketten länger als "Hello World !" sind.
Michael__W. schrieb:
mit in C++ Würde ich das so machen meinst du eine OOP Lösung durch die Klasse String, richtig ?
das ist das Beispiel, das ich aufgezeigt habe.
grüße Con@n