ASCII - Character - Hex - Bin - Dec converter

This program can be used to convert common types of data used when working with computers. It got a bit big, but the handlers are well separated, so you can set them appart and use them at your own needs. Oh, and the original (as I’m sure you noticed) is in spanish. I tried to explain a few things in english but I got bored, so learn spanish !
It is also full of little fancy things I added, such as the reference table, the default buttons or the Clipboard button.

I don’t now if the Mac ASCII table is difernt from others, or if each procesor has a different one, so this might be terribly wrong.
(let me now if it is)

I posted a very simple version of this same program a few weeks ago. You should take a look at the evolution, haha! Amazing!

OS version: OS X

-- para el Hexa - Binario - Decimal

set pedido1 to "Ingrese el valor hexa: " -- "Imput Hex value: "
set pedido2 to "Ingrese el numero binario: " -- "Imput binary numbers: "
set pedido3 to "Ingrese el numero decimal: " -- "Imput decimal number: "
set hexa to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
set binario to {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", ¬
	"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"}
global binario
global hexa

-- para el ASCII - Decimal

set pedido4 to "Ingrese el numero ASCII: " -- "Imput ASCII number: "
set pedido5 to "Ingrese el caracter: " -- "Imput character: "
set aclaracion to "(si escribe más de uno, solo será tomado en cuenta el primero de ellos)" -- if you write more than one, only the first one will be considered"
set Sin_Display to {"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", ¬
	"LF", "VT", "FF", "CR", "SO", "SI", "DLE", "DC1", "DC2", "DC3", ¬
	"DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", ¬
	"RS", "US", "Space"}
set exp to {"null", "start of heading", "start of text", "end of text", "end of transmission", ¬
	"enquiry", "acknowledge", "bell", "backspace", "horizontal tabulation", "linefeed", "vertical tabulation", ¬
	"form feed", " carriage return", "shift out", "shift in", "data link escape", "device control 1", ¬
	"device control 2", "device control 3", " device control 4", "negative acknowledge", "synchronous idle", ¬
	"end of transmission block", "cancel", "end of medium", "substitute", "escape", "file separator", ¬
	"group separator", "record separator", "unit separator", "Space"}
-- these are the characters with no on screen display
set nemo to Sin_Display
set nemo to reverse of nemo
set exp to reverse of exp
global Sin_Display
global exp
global nemo

-- los generales para todo el programa

set inicio to "Elija el modo de conversion:" -- "Choose conversion mode:"
set pregunta to "Elija como va a ingresar el dato: " -- "Choose how you want to imput the data: "
set problema to "El valor no es válido para esta conversión." -- "Not valid data for this conversion! "
global problema

repeat
	display dialog inicio buttons {"Salir", "Caracter - ASCII", "Hex - Bin - Dec"} default button 3 -- Salir = Quit
	copy the result as list to {resp}
	try
		if resp is "Caracter - ASCII" then
			display dialog pregunta buttons {"Caracter", "ASCII"} default button 2
			copy the result as list to {respuesta}
			if respuesta is equal to "ASCII" then
				display dialog pedido4 default answer "78" buttons {"OK"} default button 1
				copy the result as list to {ascii}
				set ascii to (ascii * 1) -- elimina los ceros si algun vivo puso muchos delante del numero // Takes care of any ceros the user might have written (useless ceros)
				set a to Predeterminado(ASCII character ascii) -- medio un lio, pero entonces solo tengo una funcion predeterminado
				set caracter to De_ASCII_a_Caracter(ascii) -- rutina que convierte
				set bina to De_Decimal_a_Binario(ascii)
				set bina to Agregar_Ceros(bina)
				set hex to De_Binario_a_Hexa(bina)
				display dialog the "El número ASCII " & ascii & " representa al caracter: " & caracter & return & " Corresponde al hexa: $" & hex ¬
					& return & " Y al binario: " & bina buttons {"Referencia", "Al portapapeles", "OK"} default button a
				copy the result as list to {boton}
				if boton is equal to "Al portapapeles" then
					set the clipboard to the "d" & (ascii as string) & " : " & (bina as string) & "b : $" & hex & " : \"" & caracter & "\""
					set a to the clipboard
					-- exit repeat
				else if boton is equal to "Referencia" then
					referencia()
				end if
			else if respuesta is equal to "Caracter" then
				display dialog pedido5 & return & aclaracion default answer "N" buttons {"OK"} -- sin default button porque puede querer saber el ASCII del enter. // no default since "enter"
				copy the result as list to {caracter} -- might be wanted
				set a to Predeterminado(caracter) -- establece si el boton del prox display -- Settles the default button for the next dialog (according to the selected character
				set ascii to De_Caracter_a_ASCII(caracter)
				set bina to De_Decimal_a_Binario(ASCII number caracter)
				set bina to Agregar_Ceros(bina)
				set hex to De_Binario_a_Hexa(bina)
				display dialog the "El caracter " & ascii & " es representado por el número ASCII: " & (ASCII number caracter) & return & " Corresponde al hexa: $" & hex ¬
					& return & " Y al binario: " & bina buttons {"Referencia", "Al portapapeles", "OK"} default button a
				copy the result as list to {boton}
				if boton is equal to "Al portapapeles" then
					set the clipboard to the "d" & ((ASCII number caracter) as string) & " : " & (bina as string) & "b : $" & hex & " : \"" & ascii & "\""
					--exit repeat
				else if boton is equal to "Referencia" then
					referencia()
				end if
			end if
		else if resp is "Hex - Bin - Dec" then
			display dialog pregunta buttons {"Hexa", "Binario", "Decimal"} default button 3
			copy the result as list to {respuesta}
			if respuesta is "Hexa" then
				display dialog pedido1 default answer "4E" buttons {"OK"} default button 1
				copy the result as list to {hex}
				Chequeo_Hexa(hex)
				set bina to De_Hexa_a_Binario(hex)
				set decimal to De_Binario_a_Decimal(bina)
				try -- si ingresó "FFFF" voy a tener un problema, porque no hay un caracter (me pase de 255) // if user entered "FFFF" i'll have a problem since no Character exists
					set caracter to De_ASCII_a_Caracter(decimal)
				on error
					set caracter to "el valor no tiene correspondencia con un caracter." -- "The value does not have any relation to a character
				end try
				display dialog "El hexadecimal $" & hex & "  corresponde al binario: " & bina & return & " Al decimal: " & decimal ¬
					& return & " Y al caracter: " & caracter buttons {"Referencia", "Al portapapeles", "OK"} default button 3
				copy the result as list to {boton}
				if boton is equal to "Al portapapeles" then
					set the clipboard to the "d" & (decimal as string) & " : " & (bina as string) & "b : $" & hex & " : \"" & caracter & "\""
					-- exit repeat
				else if boton is equal to "Referencia" then
					referencia2()
				end if
			else if respuesta is "Binario" then
				set retorno to ""
				display dialog pedido2 default answer "01001110" buttons {"OK"} default button 1
				copy the result as list to {bina}
				Chequeo_Binario(bina)
				set bina to Agregar_Ceros(bina)
				set hex to De_Binario_a_Hexa(bina)
				set decimal to De_Binario_a_Decimal(bina)
				try -- si ingresó "1 1111 1111" voy a tener un problema, porque no hay un caracter (me pase de ocho bits) -- same as above
					set caracter to De_ASCII_a_Caracter(decimal)
				on error
					set caracter to "el valor no tiene correspondencia con un caracter." -- same as above
				end try
				display dialog "El binario " & bina & "  corresponde al hexa: $" & hex & return & " Al decimal: " & decimal ¬
					& return & " Y al caracter: " & caracter buttons {"Referencia", "Al portapapeles", "OK"} default button 3
				copy the result as list to {boton}
				if boton is equal to "Al portapapeles" then
					set the clipboard to the "d" & (decimal as string) & " : " & (bina as string) & "b : $" & hex & " : \"" & caracter & "\""
					-- exit repeat
				else if boton is "Referencia" then
					referencia2()
				end if
			else if respuesta is "Decimal" then
				display dialog pedido3 default answer "78" buttons {"OK"} default button 1
				copy the result as list to temp
				set decimal to ((item 1 of temp) * 1) -- solo para cuando lo muestre al final, pero sin eventuales ceros que el usuario pueda haber ingresado. // cuts out ceros user might
				set bina to De_Decimal_a_Binario(decimal)
				set bina to Agregar_Ceros(bina)
				set hex to De_Binario_a_Hexa(bina)
				try -- si ingresó "1024" voy a tener un problema, porque no hay un caracter (me pase de 255) -- same as above
					set caracter to De_ASCII_a_Caracter(decimal)
				on error
					set caracter to "el valor no tiene correspondencia con un caracter." -- same as above
				end try
				display dialog "El número " & decimal & " corresponde al binario: " & bina & return & " Al hexa: $" & hex & return ¬
					& " Y al caracter: " & caracter buttons {"Al portapapeles", "OK"} default button 2
				copy the result as list to {boton}
				if boton is equal to "Al portapapeles" then
					set the clipboard to the "d" & (decimal as string) & " : " & (bina as string) & "b : $" & hex & " : \"" & caracter & "\""
					-- exit repeat
				end if
			end if
		else if resp is equal to "Salir" then
			exit repeat
		end if
	on error
		Mensaje_de_Error()
	end try
end repeat

on Mensaje_de_Error()
	beep
	display dialog problema buttons {"OK"} default button 1 with icon 2 giving up after 5
end Mensaje_de_Error

--This shows a list with an explanation of what the mnemonic means (it's in english anyway, you should get it)
on referencia() -- muestra una lista de lo que significa el mnemotécnico entregado en la respuesta ( CR = Carriage Return, por ej)
	set cant to count of nemo
	set menosonce to cant
	set i to 1
	repeat until i = 4
		set disp to ""
		set menosonce to (menosonce - 11)
		repeat until cant = menosonce
			set disp to disp & item cant of nemo & " : " & item cant of exp & return as string
			set cant to cant - 1
		end repeat
		display dialog disp & return & "Pág. " & i & " de 3" buttons {"Nota", "OK"} default button 2
		copy the result as list to {botonete}
		if botonete is equal to "Nota" then display dialog "Esta referencia solo es útil para aquellos " & return & ¬
			"caracteres sin representación gráfica." buttons {"OK"} default button 1 giving up after 5
		set i to (i + 1)
	end repeat
end referencia

--This shows the relation between Hex and binary nybbles (e.g. 1111 = F)
on referencia2() -- muestra las relaciones entre los valores hexadecimales y sus nybbles correspondientes en binario.
	set cant to (count of binario) -- o count of hexa, es igual.
	set i to 1
	set lista to ""
	repeat until i is equal to cant - 7 -- en realidad es cant - 8 + 1
		set lista to lista & return & (item i of hexa) & tab & ":" & tab & (item i of binario) & "       " & (item (i + 8) of hexa) & tab & ":" & tab & (item (i + 8) of binario)
		set i to (i + 1)
	end repeat
	display dialog "Relaciones entre valores" & return & "Hexadecimales y Binarios: " & return & lista buttons {"OK"} default button 1
end referencia2

to Predeterminado(valor) -- lo unico que hace es ver cual es el boton que va a poner como predeterminado en el proximo display
	if (ASCII number valor) <= 32 then
		set a to 1
	else
		set a to 3
	end if
	return a
end Predeterminado

to De_ASCII_a_Caracter(valor) -- convierte el numero entregado a su correspondient caracter (y se fija si tiene representación gráfica o no)
	set temp to item 1 of {valor}
	set numero to (item 1 of {valor}) as integer
	if numero <= 32 then
		set temp to item (numero + 1) of Sin_Display
	else if numero = 127 then
		set temp to "DEL"
	else
		set temp to (ASCII character valor)
	end if
	return temp
end De_ASCII_a_Caracter

to De_Caracter_a_ASCII(valor) -- convierte el primer caracter del valor entregado a su correspondiente numero ASCII
	set valor to character 1 of valor
	set temp to (ASCII number valor)
	if temp <= 32 then
		set temp to item (temp + 1) of Sin_Display
	else if temp = 127 then
		set temp to "DEL"
	else
		set temp to valor
	end if
	return temp
end De_Caracter_a_ASCII

on Chequeo_Hexa(numhexa) -- se fija si el valor ingresado por el usuario es un valor hexadecimal valido // Checks if the imputed data is a valid hex value
	set i to 1 --necesito i = 1 porque en algunos pasos uso el caracter i de numhexa, que no puede ser el 0
	repeat until i is equal to ((count of characters of numhexa) + 1) --  i es usado para las letras de numhexa 
		set letra to ""
		set j to 1
		repeat until j is equal to ((count of hexa) + 1)
			if (character i of numhexa) is equal to (item j of hexa) then
				set letra to (item j of hexa)
			end if
			set j to (j + 1)
		end repeat
		if letra is equal to "" then
			set t to (4 div 0) -- esto es a proposito, esto da error entonces salgo del try cuando se ingresa algo que no es válido // This is on purpouse, I want to return 'error'
		end if
		set i to (i + 1)
	end repeat
end Chequeo_Hexa

to De_Hexa_a_Binario(numhexa) -- convierte el valor hexadecimal (chequeado) a su correspondiente binario
	set i to 1 --necesito i = 1 porque en algunos pasos uso el caracter i de numhexa, que no puede ser el 0
	set ret to ""
	repeat until i is equal to ((count of characters of numhexa) + 1) --  i es usado para las letras de numhexa 
		set j to 1 --  j se usa para los elementos del arreglo hexa
		repeat until j is equal to ((count of hexa) + 1)
			if (character i of numhexa) is equal to (item j of hexa) then
				set ret to ret & "" & (item j of binario)
				exit repeat -- si ya lo encontro no sigo buscando
			end if
			set j to (j + 1)
		end repeat
		set i to (i + 1)
	end repeat
	return ret
end De_Hexa_a_Binario

on Chequeo_Binario(bina) -- se fija si el valor ingresado por el usuario es un valor binario valido (ceros y unos) // Checks if the numbers are 1 and/or 0
	set i to 1 --necesito i = 1 porque en algunos pasos uso el caracter i de numhexa, que no puede ser el 0
	repeat until i is equal to ((count of characters of bina) + 1) --  i es usado para las letras de numhexa 
		if (character i of bina) is not equal to "1" then
			if (character i of bina) is not equal to "0" then
				set t to (4 div 0) -- esto es a proposito, esto da error entonces salgo del try cuando se ingresa algo que no es válido // same as above
			end if
		end if
		set i to (i + 1)
	end repeat
end Chequeo_Binario


--This adds ceros to the binary number so that a set of nybbles is formed (max 3 ceros)
to Agregar_Ceros(bina)
	-- esta funcion agrega ceros hasta tener un (multiplo natural de 4) caracteres, para poder comparar con el arreglo Hexa de arriba
	set i to count of (characters of bina)
	-- i es la cantidad de ceros y unos que escribio el chabon
	set y to i - (4 * (i div 4))
	-- y es lo que sobra (max 3 bits) al restarle a i la cantidad natural de nybbles
	set ceros to ""
	if y is not 0 then -- si y distinto de cero
		set i to 0 -- i ahora es un contador
		repeat until i is (4 - y)
			set ceros to "0" & ceros -- agrega tantos ceros como falten
			set i to (i + 1)
		end repeat
	end if
	set bina to ceros & bina
	-- ahora numhexa tiene un numero de caracteres multiplo de 4 
	return bina
end Agregar_Ceros

to De_Binario_a_Hexa(bina) -- convierte el valor binario (chequeado) a su correspondiente hexadecimal
	set cant to ((count of (characters of bina)) div 4)
	set i to 1 -- i cuenta la cantidad de nybbles
	set retorno to ""
	repeat until i = cant + 1
		set j to ((4 * i) - 3) -- j lo uso para agrupar de a 4
		-- la formula es para que empiece desde donde debe segun los grupos de nybbles
		set temp to ""
		repeat until j = ((4 * i) + 1)
			set temp to temp & (item j of bina)
			set j to (j + 1)
		end repeat -- termine de agrupar el nybble
		set k to 1
		repeat until k is equal to ((count of binario) + 1)
			if temp is equal to (item k of binario) then
				set retorno to retorno & (item k of hexa)
				exit repeat -- si ya lo encontre paro
			end if
			set k to (k + 1)
		end repeat -- termine de buscar el hexa correspondiente
		set i to (i + 1)
	end repeat -- termine de convertir todo
	return retorno
end De_Binario_a_Hexa

to De_Decimal_a_Binario(decimal)
	set cant to (count of characters of (decimal as string))
	set valor to ""
	set i to 0
	repeat until i is equal to 1
		set valor to (((decimal) - (2 * (decimal div 2))) as string) & valor -- esto da 0 o 1 siempre
		set decimal to (decimal div 2) -- hace la division con resto, siempro 0 o 1
		if decimal is equal to 0 then set i to (i + 1) -- si por alguna razon nunca pasa se pudre todo, porque i no lo incremento ni nada
	end repeat
	return valor
end De_Decimal_a_Binario

to De_Binario_a_Decimal(temp)
	set cant to (count of characters of temp)
	set valor to 0
	set i to cant - 1
	set j to 1
	repeat until i is equal to (-1)
		set valor to valor + ((character j of temp) * (2 ^ i))
		set i to (i - 1)
		set j to (j + 1)
	end repeat
	return valor
end De_Binario_a_Decimal


-- a few tests I did
(*
d65 : 01000001b : $41 : "A"	d11 : 1011b : $B : "VT"	este no se porque no tengo ese boton	estos dos no se pueden porque no tienen sentido (como dice abajo)
d66 : 01000010b : $42 : "B"	d10 : 1010b : $A : "LF"	d127 : 01111111b : $7F : "DEL"	
d67 : 01000011b : $43 : "C"	d9 : 1001b : $9 : "HT"	d127 : 01111111b : $7f : "DEL"	d333 : 000101001101b : $14d : "el valor no tiene correspondencia con un caracter."
d68 : 01000100b : $44 : "D"	d8 : 1000b : $8 : "BS"	d127 : 01111111b : $7F : "DEL"	d333 : 000101001101b : $14D : "el valor no tiene correspondencia con un caracter."
d69 : 01000101b : $45 : "E"	d7 : 0111b : $7 : "BEL"	d127 : 01111111b : $7F : "DEL"	d333 : 000101001101b : $14D : "el valor no tiene correspondencia con un caracter."
*)