Code-Schnipsel
Moderatoren: broesel, Martin Conrad, PatrickThema: hex2ascii
void hex2ascii (char *s){
int x=0, y=0;
if (NULL==s)
return;
for (;s[y];++x,++y){
// s[y]=='%'
if (s[y]==37){
// hexadezimale Zeichenfolge in ASCII Code umwandeln
s[x]=(s[y+1]>=65 ? ((s[y+1] & 0xDF) - 55) : (s[y+1]-48));
s[x]<<=4;
s[x]+=(s[y+2]>=65 ? ((s[y+2] & 0xDF) - 55) : (s[y+2]-48));
y+=2;
}
else
s[x] = (s[y]==43 ? 32 : s[y]);
/*
gültigen Bereich festlegen;
muss nicht, kann aber nutzlich sein;
*/
if (s[x]<32 || s[x]>126)
x--;
}
s[x]=0;
return;
}
--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.
[EDIT] - Re: hex2ascii
Patrick (Moderator) am 10.03.2006 um 19:31
Vieleicht benutzt ja sonst noch wer ausser mir Juergens Code und kann diese abgeänderte Version gebrauchen bzw. verbessern
--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.
Re: hex2ascii
Patrick (Moderator) am 04.08.2010 um 15:29
Die oben genannte Funktion nutze ich derzeit unter dem Namen urldecode.
/*******************************************************************************
* URL-kodiert einen String.
* Gibt einen String zurueck, in dem alle nicht-alphanumerischen Zeichen durch
* ein Prozentzeichen (%) gefolgt von zwei Hexadezimalwerten ersetzt werden.
* Ausnahmen bilden '-' (Minus), '_' (Unterstrich), '.' (Punkt) und ' '
* (Leerzeichen). Leerzeichen werden durch ein '+' (Plus) ersetzt, die uebrigen
* Ausnahmen bleiben wie alphanumerische Zeichen erhalten.
*
* @param Zeiger auf dekodierten String.
* @param Zeiger auf encodierten String.
*******************************************************************************/
inline
static
char *urlencode ( const char *string )
{
if (NULL == string)
return NULL;
char *encoded = malloc(strlen(string)*3 +1);
if (NULL == encoded)
die("urlencode() Speicherreservierung fehlgeschlagen.");
unsigned long i=0, p=0;
for (; string[i]; i++)
{
if (string[i] < 45
|| (string[i] > 46 && string[i] < 48)
|| (string[i] > 57 && string[i] < 65)
|| (string[i] > 90 && string[i] < 97 && string[i] != 95)
|| string[i] > 122)
{
encoded[p++]='%';
sprintf((encoded+p), "%02X", (unsigned char)string[i]);
p+=2;
}
else
encoded[p++]=string[i];
}
encoded[p]='\0';
return encoded;
}
Insbesondere die Zeile
sprintf((encoded+p), "%02X", (unsigned char)string[i]);
stört mich noch, es musste einfach nur schnell funktionieren.
Verbesserungsvorschläge?
--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.
Re: hex2ascii
broesel (webmaster) am 04.08.2010 um 16:17
in solchen Fällen wie diesem, wo Speicher reserviert wird und damit dann irgendwas gemacht wird (Standardbeispiel: explode()), ist es ratsame Praxis, eine Version zu bauen die mit "statischem Speicher" auskommt, und darauf aufbauend dann eine Wrapper-Funktion, die entsprechend Speicher reserviert und dann die statische Version aufruft:
#define is_urlencode_special_char(c) (!(isalnum(c) || (strchr("-_ .:/?&@", c) != NULL)))
void urlencode_s(char *dest, const char *src)
{
while (src && *src) {
if (is_urlencode_special_char(*src)) {
*dest++ = '%';
*dest++ = "0123456789ABCDEF"[(*src & 0xF0) >> 4];
*dest++ = "0123456789ABCDEF"[(*src & 0x0F)];
} else if (*src == ' ') {
*dest++ = '+';
} else {
*dest++ = *src;
}
src++;
}
*dest = '\0';
}
char *urlencode(const char *src)
{
char *ret = NULL;
char *p = (char *)src;
int num = 0;
while (p && *p) {
if(is_urlencode_special_char(*p))
num += 3;
else
num += 1;
++p;
}
ret = malloc(num + 1);
if (ret == NULL)
return NULL;
urlencode_s(ret, src);
return ret;
}
Das hat den Vorteil, dass der Benutzer entscheiden kann, wie er's denn gerne hätte, und in erster Linie natürlich dass man nur so viel Speicher reserviert, wie man auch tatsächlich braucht. strlen(string)*3+1 ist eine äusserst schlechte obere Schranke für den benötigten Platz.
Das nervige sprintf() wird man los, wenn man einen Lookup-Table baut (in unserem Fall den String "0123456789ABCDEF") und als Index den ASCII-Wert des jeweiligen Zeichens und ein bißchen Bit-Rumgeschiebe.
Weiterhin solltest Du beachten, dass @, :, ? und & üblicherweise nicht ersetzt werden. @ und : braucht man, um Benutzername und Passwort an Seiten zu übermitteln, also z.B. http://username:password@www.google.de/, und ? und & sind ja eh klar...
Möglich, dass es da noch andere Zeichen gibt, die üblicherweise nicht kodiert werden.
Hoffe, ich konnte Dir helfen. Ich hab mir das alles gerade aus dem Ärmel gezaubert, möglich dass sich da noch der ein oder andere Fehler versteckt.
Gruss,
Philip
--
The C Programming Quiz
- bitte Fragen einreichen :)
[EDIT] - Re: hex2ascii
Patrick (Moderator) am 05.08.2010 um 08:23
Zitat:
Weiterhin solltest Du beachten, dass @, :, ? und & üblicherweise nicht ersetzt werden. @ und : braucht man, um Benutzername und Passwort an Seiten zu übermitteln, also z.B. http://username:password@www.google.de/, und ? und & sind ja eh klar...
Afaik stimmt das nicht ganz.
Die von dir genannten Zeichen haben eine Sonderstellung, ganz klar.
Sind diese Zeichen aber Bestandteil eines Parameterwertes, so müssen sie sehr wohl urlenkodiert werden.
Soll z.B. der Parameter 'msg' den Text 'thx&bye' enthalten, wird 'msg' urlenkodiert zu 'msg', gefolgt von einem Gleichzeichen '=', gefolgt vom urlenkodierten 'thx&bye' - 'thx%26bye'.
Das Ergebnis wäre dann also 'msg=thx%26bye' und nicht 'msg%3Dthx%26bye' oder 'msg=thx&bye'.
thx%26bye
--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.
