// byte2nibble.cpp
// G.Heinz heinz@gfai.de
// Zerlegung eines Byte in zwei Nibble, die als ASCII-Byte ausgegeben werden.
// Dient der Übertragung einer beliebigen Hexzahl durch zwei ASCII (jeweils 0...9, a...f)

#include "stdafx.h"
//#include <stdio.h>


void b2n(char *hi, char *lo, char in) {	// Input: in-Byte,	Output: hi- and lo- Nibbles als ASCII
	// gibt die zwei Nibble (0...f) des in-Byte als ASCIIs aus
	static char const alphabet[] = "0123456789abcdef";	// ein char-Array wird als lookup-table genutzt
	(*hi) = alphabet[ (in >> 4) & 0x0f ];		// Index um vier Bit rechts schieben, links mit Nullen gefüllt
	(*lo) = alphabet[ in & 0x0f ];		// hohes Nibble nullen
}

char a2h(char asc) {			// ascii to hex
	// input: ascii(0...f), out: hex 0x00...0x0f
	if (asc < 0x3a) {			// 0...9
		return (asc & 0x0f);	// das low-Nibble hat den gesuchten Wert
	}
	else {						// a...f
		return ((asc & 0x0f) + 9 );	// siehe ASCII-Tabelle
	}
}

void n2b(char hi, char lo, char *out) {	// nibbles to byte
	// setzt ein Byte aus zwei hex-Nibbles zusammen
	// setzt voraus, daß Nibbles als ASCII zwischen 0...f liegen
	(*out) = (((a2h(hi) << 4) & 0xf0) | a2h(lo));	// hi um 4 Bit nach links schieben
	/* langsam zum Mitdenken:
	char hi, lo, tmp;
	hi = a2h(hi);			// hex aus ascii machen
	hi = (hi << 4) & 0xf0;	// um 4 bit links schieben und maskieren
	lo = a2h(lo);			// hex aus ascii machen 
	tmp = (hi | lo);		// Oren (nicht Anden)
	(*out) = tmp;
	*/
}

int main()
{
	char hi, lo, in, out, mist;
	printf ("\n\n(Abbruch mit CTRL-C)\n\n");
	anf:
	printf ("Ein Zeichen eingeben: ");
    scanf  ("%c", &in);		// Zeichen annehmen
    scanf  ("%c", &mist);	// CR abfangen und verwerfen

	// Byte to Nibbles:
	b2n(&hi, &lo, in);		// input: in, output: hi, lo
	printf("\n ASCII '%c' = 0x%x --> [H,L] = ['%c', '%c'] = hex %c%c \n\n", in, in, hi, lo, hi, lo);

	// Verifikation:
	n2b(hi, lo, &out);		// input: hi, lo	output: out
	printf(" [H,L] = ['%c', '%c'] = hex %c%c --> 0x%x = ASCII '%c' \n\n", hi, lo, hi, lo, out, out);

	goto anf;
	return 0;
}


/* Ausgaben /////////////////////////////////////////////////////


(Abbruch mit CTRL-C)

Ein Zeichen eingeben: 0

 ASCII '0' = 0x30 --> [H,L] = ['3', '0'] = hex 30

 [H,L] = ['3', '0'] = hex 30 --> 0x30 = ASCII '0'

Ein Zeichen eingeben: t

 ASCII 't' = 0x74 --> [H,L] = ['7', '4'] = hex 74

 [H,L] = ['7', '4'] = hex 74 --> 0x74 = ASCII 't'

Ein Zeichen eingeben: 9

 ASCII '9' = 0x39 --> [H,L] = ['3', '9'] = hex 39

 [H,L] = ['3', '9'] = hex 39 --> 0x39 = ASCII '9'

Ein Zeichen eingeben: f

 ASCII 'f' = 0x66 --> [H,L] = ['6', '6'] = hex 66

 [H,L] = ['6', '6'] = hex 66 --> 0x66 = ASCII 'f'

Ein Zeichen eingeben: a

 ASCII 'a' = 0x61 --> [H,L] = ['6', '1'] = hex 61

 [H,L] = ['6', '1'] = hex 61 --> 0x61 = ASCII 'a'

Ein Zeichen eingeben: (CR) (CR)

 ASCII '' = 0xa --> [H,L] = ['0', 'a'] = hex 0a

 [H,L] = ['0', 'a'] = hex 0a --> 0xa = ASCII ''

Ein Zeichen eingeben: ³

 ASCII '³' = 0xfffffffc --> [H,L] = ['f', 'c'] = hex fc

 [H,L] = ['f', 'c'] = hex fc --> 0xfffffffc = ASCII '³'

Ein Zeichen eingeben: ß

 ASCII 'ß' = 0xffffffe1 --> [H,L] = ['e', '1'] = hex e1

 [H,L] = ['e', '1'] = hex e1 --> 0xffffffe1 = ASCII 'ß'

Ein Zeichen eingeben: @

 ASCII '@' = 0x40 --> [H,L] = ['4', '0'] = hex 40

 [H,L] = ['4', '0'] = hex 40 --> 0x40 = ASCII '@'

Ein Zeichen eingeben: §

 ASCII '§' = 0xfffffff5 --> [H,L] = ['f', '5'] = hex f5

 [H,L] = ['f', '5'] = hex f5 --> 0xfffffff5 = ASCII '§'

Ein Zeichen eingeben: &

 ASCII '&' = 0x26 --> [H,L] = ['2', '6'] = hex 26

 [H,L] = ['2', '6'] = hex 26 --> 0x26 = ASCII '&'

Ein Zeichen eingeben: $

 ASCII '$' = 0x24 --> [H,L] = ['2', '4'] = hex 24

 [H,L] = ['2', '4'] = hex 24 --> 0x24 = ASCII '$'

Ein Zeichen eingeben:
*/
