[c++] unsigned char* -> hex && hex -> unsigned char*

kickerxy123

Erfahrenes Mitglied
Hi, mal wieder ein kleines Problem.
C++:
        char hexVal[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
                           'A', 'B', 'C', 'D', 'E', 'F' }; 

        string s = "";
//unsigned char -> hashRep string
	for(int i = 0; i < shaedInLen; ++i)
	{
		s+= hexVal[((unsigned int)shaedIn[i]) >> 4];
		s+= hexVal[((unsigned int)shaedIn[i]) & 0xF];
	 }

//hashRep string -> unsigned char
	*pOutShaLen = s.length() / 2;
	*pOutSha = new unsigned char[*pOutShaLen];
	
	for(int i = 0; i < s.length(); i+=2)
	{
 		(*pOutSha)[i/2] = (unsigned char)(hexVal[((unsigned int)s[i]) << 4] + hexVal[((unsigned int)s[i+1]) & 0xF]);
	}
Ich frage mich was hier schief läuft? Das Ergebnis am Ende entspricht nicht dem Input am Anfang.
Der Hex String nach dem ersten Teil sieht eigentlich ganz gut aus, denke der zweite Teil ist fehlerhaft.

danke!
kickerxy
 
Zuletzt bearbeitet:
Hi.

Du konvertierst Bytes zu Chars und dann... Chars zu Chars.(?)

hexVal nützt dir im zweiten Schritt nichts, du müßtest theoretisch den Index des Zeichens im Array finden. (Ganz zu schweigen davon das du weit über die Grenzen das Arrays hinaus zugreifst)

"3F" => 0x3 << 4 + 0xf
 
Hi und danke für die schnelle Antwort.
Ja irgendwie hat das in der Tat wenig Sinn ergeben.

C++:
	for(int i = 0; i < in.length(); ++i)
	{
		for(int t = 0; t < hexValLen; ++t)
		{
			if(hexVal[t] == in[i])
			{
				if(i % 2 == 0)
					(*pOutSha)[(int)(i/2)] = (unsigned char)(t << 4);
				else
					(*pOutSha)[(int)(i/2)] += (unsigned char)(t & 0xF);
				break;
			}
		}
	}
Ist nun mein neuer Ansatz. hexValLen == 16. Das geht leider auch nicht. Kannst du mir sagen, was ich verändern muss?
 
Hi.

Mit dem Wort "theoretisch" meinte ich, das du es nicht so machen solltest.

C++:
inline int unhex(int c) {
  return (std::isdigit(c) ? c - '0' : std::tolower(c) - 'a');
}

for (...) {
  (*pOutSha) = unhex(s[i]) << 4 | unhex(s[i + 1]);
}
 
Danke,
das klappt super (meins zwar auch, aber deins ist in der Tat sinnvoller). Hatte noch woanders ein Fehler..


viele Grüße
 
Hallo nochmal,

das Thema ist unerwarteterweise doch noch nicht erledigt.

C++:
static char hexArr[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

std::string tostring(unsigned char* uchar, int ucharLen)
{
	std::string ret = "";
 	for(int i = 0; i < ucharLen; ++i)
    {
        ret+= hexArr[((unsigned int)uchar[i]) >> 4];
        ret+= hexArr[((unsigned int)uchar[i]) & 0xF];
     }
	return ret;
}

inline int unhex(unsigned int c)
{
	return (std::isdigit(c) ? c - '0' : std::toupper(c) - 'A');
}

bool to_uchar(string in, unsigned char** pOut, int* pOutLen)
{
	*pOutLen= in.length() / 2;
	*pOut = new unsigned char[*pOutLen]; 

	for (int i = 0; i < in.length(); i+=2)
 		(*pOut)[i/2] = (unsigned char) (unhex(in[i]) << 4 | unhex(in[i + 1]));
 
	return true;
}
Fehlerüberprüfungen hier weggelassen. Namen zT verändert.

Wenn ich mir ein Uchar initialisiere mit ein paar hundert random bytes und
C++:
unsigned char* data = new unsigned char[800], * data2;
//fill
string r = tostring(data, 800);
to_uchar(r, &data2, &data2Len);
string s = tostring(data2, data2Len),
erhalte ich s != r (aber gleiche Länge).

Sie sind sich allerdings sehr ähnlich:
C++:
s: 020000003131000200004342304544323734434334414631443043304344433743414332334134333732373431394141334538363638444543453146313839463741343242384642363438453342334143423644344141323634344532433831354445354530384336344631334134463546454346344632363933323644344235434541324445323435423031434246393144414435393131303532364632434235324541453232334137424233413242334530383439383934314642464139364536323131434246313244314533314343314239433832383533444134394335433136393545363546433945374132463636314634313346354534464334464132383836353636374232333842314533304239384234434130333332394646393738464236313141384330394632324241434135344346303838313632364542344344414243363445353934314435323130393841413637374643444538434446444137384145333235454332353536444244453444334239363943393345353944433530384438364532463335433046304634314445373045363230303645334246364433343146363443303642443333443242393445343945394235334346413741384245364336414434383731443345354543384431424439334432354243354445434634433634464344323143304245304432434136353030413437303042363937414346000000010000743473215914642470299092443025219532276323401600421013330838362831511407154703267147029035901535735843163139557058199822288431898020243766020302181743480034397146129531510322566356675261854103574305504380300274519233102961763312524238451422834354811401570115574156140014630437935833013913750583352510022364134173341034807137969189981808444266095950953385121106038207202872500656721197373172846095050178153518244916144056596049615651054543631133053702051201104953231284815524342717473072055332557519743515375821130000000011359230224735205849



r: 02000000313100020000434230454432373443433441463144304330434443374341433233413433373237343139414133453836363844454345314631383946374134324238464236343845334233414342364434414132363434453243383135444535453038433634463133413446354645434634463236393332364434423543454132444532343542303143424639314441443539313130353236463243423532454145323233413742423341324233453038343938393431464246413936453632313143424631324431453331434331423943383238353344413439433543313639354536354643394537413246363631463431334635453446433446413238383635363637423233384231453330423938423443413033333239464639373846423631314138433039463232424143413534434630383831363236454234434441424336344535393431443532313039384141363737464344453843444644413738414533323545433235353644424445344433423936394339334535394443353038443836453246333543304630463431444537304536323030364533424636443334314636344330364244333344324239344534394539423533434641374138424536433641443438373144334535454338443142443933443235424335444543463443363446434432314330424530443243413635303041343730304236393741434600000001000074D47D2B591E64247A299A9C443AC52B95D22763CD4A16004CBA133308D8D628D15114071F47AD267147AC9035901FDF7D58ED1631395F7058199822C884D18980C02ED7660CAD0C18B74DE800DED97BE6B29531FBA32CF66DF667FC6185EB03574D05FAED8ADAAC74F19C3310C9617633B25C42D84FB4C28343F48BB4A1F70BBFF7E1561400B4630ED793F83D01D9137F058D35C5100C23641D4B7DDEB0348071D7969B8998B8A84E4C6609595A9F338F1C1106A38C07CAC87CFAA6567C1197D7DB728E6A95050B7815D5B82E4916144A56F960E961565105E54363BB3D0F3702AFB20B1A495DCD128481F524DEC71747307C0FFD3CF57F19743F15D7F8C1B30A00000011359CD022E7D520F8E9

(die ersten 529 sind identisch, erst dann treten ab und an kleine abweichungen auf)
Bin über Hilfe hierbei dankbar!
viele Grüße
 
Sorry für diesen erneuten Post, aber ich denke es ist übersichtlicher, als wenn ich den alten editiere.


Habe eine Lösung gefunden:


C++:
inline int unhex(unsigned int c)
{
    return (std::isdigit(c) ? c - '0' : std::toupper(c) - 'A' + 10);
}
man beachte die "+10" als einzige Änderung. Nun funktioniert alles bestens :)
gruß
kickerxy
 
Zurück