Skip to content

Instantly share code, notes, and snippets.

@franklopeslr
Last active January 26, 2020 00:10
Show Gist options
  • Save franklopeslr/0e692c4fb32712d7ad7d7e0dd593a62f to your computer and use it in GitHub Desktop.
Save franklopeslr/0e692c4fb32712d7ad7d7e0dd593a62f to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
// mapa de caracteres
#define A_AGUDO 65380
#define A_CRASE 65379
#define A_TIL 65382
#define E_AGUDO 65388
#define E_CIRCUN 65389
#define O_AGUDO 65398
#define O_CIRCUN 65399
#define O_TIL 65400
#define C_CEDIL 65386
#define alloc(size) (char*) malloc((size) * sizeof(char))
// passa para forma binaria
void binary(char utf8_char, char * bits)
{
#define BINARY_BASE 0b00000001
for(uint8_t i = 0; i < 8; i++)
{
uint8_t bit = (utf8_char >> i) & BINARY_BASE;
if(bit)
{
bits[7u - i] = '1';
}
else
{
bits[7u - i] = '0';
}
}
}
// conta numero de bytes a partir das flags no msb
uint8_t utf8_n_bytes(char utf8)
{
uint8_t counter = 1;
char msb[9] = {'\0'};
binary(utf8, msb);
// msb 0 indica que vai de 0..127
if(msb[0] == '0')
{
return 1;
}
// ate chegar na flag de fim do contador
// 1...0xxxx
for(; msb[counter] != '0'; counter++);
return counter;
}
// converte UTF-8 para ASCII padrao
char * utf8_2_ascii(char * utf8)
{
// tamanho da cadeia ascii final
uint8_t ascii_length = 1;
// ascii final
char * ascii = alloc(1);
// caractere ascii que ira ficar no lugar dos utf-8 com acentos latinos
char babbel = '\0';
// itera toda a string, verificando o numero de bytes que o msb aponta
// se o caractere usa apenas 1 byte (0xxxxxxx), entao ja esta em ascii
// se usa mais ou mais >= 2 bytes (110xxxxx)(10xxxx)..(10xxxx), entao os bytes
// sao pulados ate achar um em ascii
// se os carecteres com acentuacao latinos forem achados, entao sao substituidos
// pelos caracteres sem os acentos
for(uint32_t i = 0; utf8[i] != '\0'; i++)
{
uint8_t n_bytes = utf8_n_bytes(utf8[i]);
if(n_bytes == 1)
{
// apenas adiciona ao ascii final
ascii[ascii_length-1] = utf8[i];
ascii_length += 1;
ascii = (char*) realloc(ascii, ascii_length);
}
else
{
// valor numerico do caractere em forma de soma
// do valor dos bytes
uint16_t sum_utf8_code = 0;
// soma os valores dos bytes do caractere
for(uint8_t aux = 0; aux < n_bytes; aux++)
{
sum_utf8_code += utf8[i + aux];
}
// verifica qual letra corresponde
// se nao houver, nulo '\0' eh setado
switch(sum_utf8_code)
{
case A_AGUDO:
case A_TIL:
case A_CRASE:
babbel = 'a';
break;
case E_AGUDO:
case E_CIRCUN:
babbel = 'e';
break;
case O_AGUDO:
case O_TIL:
case O_CIRCUN:
babbel = 'o';
break;
case C_CEDIL:
babbel = 'c';
break;
default:
babbel = '\0';
}
if(babbel != '\0')
{
// se houver letras latinas acentuadas,
// adiciona o caractere corresponde sem
// acento ao ascii final
ascii[ascii_length-1] = babbel;
ascii_length += 1;
ascii = (char*) realloc(ascii, ascii_length);
}
// pula os bytes do utf non-ascii
i += n_bytes - 1;
}
}
// EOS
ascii = (char*) realloc(ascii, ascii_length + 1);
ascii[ascii_length] = '\0';
return ascii;
}
// mostra os bits do caractere
void utf8_bits(char * utf8)
{
for(uint32_t i = 0; utf8[i] != '\0'; i++)
{
char b[9] = {'\0'};
binary(utf8[i], b);
printf("%8s ", b);
}
printf("\n");
}
int main(uint32_t argc, char * argv[])
{
char * ascii = NULL;
char buff[2056];
while(1)
{
printf(">");
scanf("%s", buff);
if(strcmp(buff, ".sair") == 0)
{
printf("até mais :)\n");
break;
}
ascii = utf8_2_ascii(buff);
printf("em ascii: %s\n", ascii);
free(ascii);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment