„Base64“ kodavimo biblioteka su „Arduino“.
Pagrindas64 yra kodavimo sistema, kuri naudoja 64 simbolius, sugrupuotus į pranešimus, kurių ilgis yra keturių kartotinis. Šie pranešimai (duomenų paketai) prireikus užpildomi pliuso simboliu (todėl naudojami 65), dažnai lygybės ženklu (=), jei užkoduota naudinga informacija yra trumpesnė.
Naudodami 64 ženklus galite dirbti su 10 kodo skaičių ir didžiosiomis bei mažosiomis raidėmis (26+26). ASCII, problema ta, kad yra 62, tarkime, nedviprasmiški simboliai plius du, kurie skiriasi įvairiais būdais. Nors kartais tai vadinama posakiu „simboliai ASCII spausdinami“, iš tikrųjų tai yra tie, kurie svyruoja nuo kodo 32 (tarpo) iki 126 (~) 95, kuriuos tikrai galima spausdinti.
Kodavimo įgyvendinimas Pagrindas64 dažniausiai naudojamas, kad iš PEM, kurį taip pat naudoja Mime, dirbkite su papildomais „+“ ir „/“ ženklais ir „=“ ženklu, kad paketų ilgis būtų kartotinis iš keturių. Raidės A–Z užima 0–25 pozicijas, raidės a–z – 26–51, skaičiai 0–9 – 52–61, pliuso ženklas (+) – 62, o 63 – pasvirasis brūkšnys (/ ).
Duomenų pateikimo formatu būdas Pagrindas64 susideda iš pradinių duomenų paėmimo iš grupių 6 bitai kurie pavaizduoti atitinkamu kodu. Jei liko bitų, jie užpildomi nuliais į dešinę. Jei gautas kodų skaičius nėra keturių kartotinis, jis užpildomas lygybės ženklais dešinėje.
Toliau pateiktame paveikslėlyje parodytas kodavimas ASCII teksto („ohm“) ir būdo, kuriuo jis konvertuojamas Pagrindas64. Kadangi yra 7 simboliai, galutinis pranešimas turėtų būti užpildytas lygybės ženklu. Galima sakyti, kad tekstas „ohm“ in ASCII atitinka «b2htaW8=" in Pagrindas64.
Konkreti kodavimo paskirtis Pagrindas64 Jie taip pat paprastai nustato maksimalų linijos ilgį. Įgyvendinimas Mime Apriboja kiekvieną eilutę iki 76 simbolių. Paprastai eilutės bus atskirtos eilutės pabaigos kodu (CR, vaizduojama reikšme 0x0D ASCII) ir dar viena nauja eilutė (NL, kuri atitinka kodą ASCII 0x0A).
Nepatogumai, kurie pridedami diegiant kodavimą Pagrindas64 mažai išteklių turinčiame įrenginyje, kaip dažnai būna su a mikrovaldiklis yra tai, kad turite koduoti, kai gaunama informacija arba su a buferis minimumas, kuris taip pat reikalauja pateikti sistemą, kuri rodo, kad pradinio pranešimo pabaiga pasiekta, pavyzdžiui, pridedant specialų kodą arba naudojant PIN kodą, kurio lygis (sinchronizuotas su priėmimu) rodo pranešimo būseną.
Žemiau pateiktas kodo pavyzdys yra a biblioteka, skirta Arduino koduoti Base64 kuri įgyvendinama naudojant abu kriterijus: gaunamos informacijos užkodavimas (be a buferis) ir palaukite, kol baigsis įspėjamasis signalas.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
//base64.h
#include <string.h> // memcpy/strncpy
#define LONGITUD_LINEA 76
#define MASCARA_B64 0B00111111
#define ULTIMO_CODIGO_BASE64 64 // 64 caracteres más el signo igual (empezando a contar desde cero)
#define MAXIMA_LONGITUD_RESULTADO 6 // Máximo número de caracteres del resultado parcial de la codificación. Puede ser 1 si no se ha llegado al final de un bloque (2 bytes en el original, 4 en la conversión), 2 si se ha llegado al final de un bloque, 3 si no se ha llegado al final de un bloque pero se supera la longitud máxima de la línea, 4 si se llega al final de un bloque y se supera la longitud máxima de la línea, 5 si hay que rellenar con un signo igual o 6 si hay que rellenar con dos signos igual
class Base64
{
private:
unsigned char simbolo_base64[ULTIMO_CODIGO_BASE64+1]; // Espacio para la codificación Base64, el relleno (=) una terminación en \0
unsigned int numero_valor; // Posición (empezando en cero) que ocupa el valor que se desea convertir en el mensaje completo original
unsigned int numero_codigo; // Posición del último código calculado. Podría limitarse al ancho de la línea (LONGITUD_LINEA, 76 caracteres) pero usando un contenedor alto se podría implementar también una cuenta estadística
unsigned char resto_base64; // Último resto obtenido al calcular el último código
unsigned char resultado[MAXIMA_LONGITUD_RESULTADO+1]; // Resultado de la conversión actual. Si es terminal puede incluir el caracter 65 (=) una o dos veces
unsigned char contador_caracteres_resultado=0;
void acumular_resultado(unsigned char valor);
public:
Base64();
~Base64();
void iniciar_conversion();
unsigned char *convertir(unsigned char valor_original, bool terminar_conversion);
unsigned char *convertir(unsigned char valor_original);
unsigned char *terminar();
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
//base64.cpp
#include “base64.h”
Base64::Base64() // Constructor
{
memcpy(simbolo_base64,“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=”,ULTIMO_CODIGO_BASE64+1);
iniciar_conversion();
}
Base64::~Base64() // Destructor
{
}
void Base64::iniciar_conversion()
{
numero_valor=0;
numero_codigo=0;
resto_base64=0;
}
unsigned char *Base64::convertir(unsigned char valor_original, bool terminar_conversion) // Valor que se desea convertir a Base64
{
convertir(valor_original);
if(terminar_conversion)
{
terminar();
}
return resultado;
}
unsigned char *Base64::convertir(unsigned char valor_original) // Valor que se desea convertir a Base64
{
unsigned char desplazamiento;
contador_caracteres_resultado=0;
acumular_resultado((valor_original>>(2+(numero_valor%3)*2))|resto_base64);
desplazamiento=4–(numero_valor%3)*2;
resto_base64=(valor_original&(MASCARA_B64>>desplazamiento))<<desplazamiento;
if(((numero_codigo+1)%4==0))
{
acumular_resultado(resto_base64);
resto_base64=0;
}
numero_valor++;
resultado[contador_caracteres_resultado]=0;
return resultado;
}
unsigned char *Base64::terminar()
{
if(numero_codigo%4)
{
acumular_resultado(resto_base64);
while(numero_codigo%4)
{
acumular_resultado(ULTIMO_CODIGO_BASE64);
}
}
resultado[contador_caracteres_resultado]=0;
iniciar_conversion();
return resultado;
}
void Base64::acumular_resultado(unsigned char valor)
{
numero_codigo++;
resultado[contador_caracteres_resultado++]=simbolo_base64[valor];
if((numero_codigo%LONGITUD_LINEA)==0)
{
resultado[contador_caracteres_resultado++]=13; // CR “\r”
resultado[contador_caracteres_resultado++]=10; // LF “\n”
}
}
|
Pagrindinė kodo skaičiavimo dalis Pagrindas64 Tai daroma su tokia išraiška:
(valor_original>>(2+(numero_valor%3)*2))|resto_base64
o likusios dalies apskaičiavimas su išraiška:
(valor_original&(MASCARA_B64>>desplazamiento))<<desplazamiento
,
esamas desplazamiento
reikšmė, kuri apskaičiuojama naudojant išraišką:
4-(numero_valor%3)*2
Norint gauti šias išraiškas, reikia apibendrinti kiekvieno iš keturių kodų skaičiavimą Pagrindas64 kurie atsiranda atvaizduojant tris pradinės vertės baitus.
Base64=((byte_1>>2)|resto)&0b00111111 |
resto=(byte_1&0b00000011)<<4 |
Base64=((byte_2>>4)|resto)&0b00111111 |
resto=(byte_2&0b00001111)<<2 |
Base64=((byte_3>>6)|resto)&0b00111111 |
resto=(byte_3&0b00111111)<<0 |
Base64=((byte_3>>0)|resto)&0b00111111 |
resto=(byte_3&0b00111111)<<0 |
Su tekstu Base64
Aukščiau pateiktas pseudokodas nurodo kodą Pagrindas64 kad skaičiuojama. Posakis buvo naudojamas byte_n
nurodyti koduojamą n-ąjį baitą. Tekstas resto
reiškia likusius koduojamo baito bitus. Skaičiavimo pradžioje daroma prielaida, kad likusi dalis yra lygi nuliui
Siekiant aiškumo, ankstesniame pseudokode 6 bitų kaukė buvo įtraukta į visų kodų skaičiavimą, nors reikia nustatyti tik paskutinį iš jų, nes kiti yra pasukti taip, kad du daugiausiai bitų visada būtų prarasti. reikšmingas.
Kaip matote, ketvirtasis kodas yra visas liekanas ir likučio vėliau skaičiuoti nereikia; Todėl reikia atlikti tik tris veiksmus, po vieną kiekvienam užkoduotam baitui. Svarbu atsiminti, kad jei trečiasis baitas pakete nebūtų užkoduotas, paskutinis kodas turės būti užpildytas nuliais dešinėje. Pagrindas64 gautas.
Apibendrinant, teisingas išraiškos, apskaičiuojančios kodą, pasukimas Pagrindas64 gali būti pavaizduotas kaip 2+(numero_byte%3)*2
kad skliausteliuose esanti dalis pasisuktų nuo nulio iki dviejų, todėl kiekviename žingsnyje būtų 2, 4 ir 6. Žinoma, tai nėra vienintelis būdas apibendrinti, bet pasirinkau šį variantą dėl funkcionalumo ir visų pirma dėl aiškumo. Kadangi kaukė (IR) buvo reikalinga tik ketvirtame kode ir jau matėsi, kad jos skaičiuoti nereikia (visas liekanas), ji neįtraukiama į galutinę išraišką, kad ją supaprastintume, nors turime prisiminti kad naudojamų duomenų tipas (baitas ) imami tik 6 mažiausiai reikšmingi bitai.
Likusių sukimąsi į kairę galima apibendrinti analogiškai ankstesniajam. Taip pat galima pastebėti, kad uždedama kaukė (IR) sukasi tuo pačiu bitu, bet priešinga kryptimi. Tai yra priežastis, dėl kurios reikia apskaičiuoti poslinkį 4-(numero_valor%3)*2
prieš taikydami ją kiekvieną išraiškos dalį atitinkančia prasme.
Toliau pateiktame pavyzdyje parodyta, kaip naudoti biblioteką teksto eilutei koduoti (atminkite, kad Pagrindas64 gali būti naudojamas bet kokiam duomenų rinkiniui, pvz., vaizdui). Šiame kode yra keletas detalių, kurias įdomu paaiškinti. Pirma, specialus simbolis (simbolis ~) buvo naudojamas norint nurodyti teksto pabaigą, o ne aparatūros signalą arba nurodant teksto ilgį. Logiškai mąstant, šis simbolis negali būti užkoduotų duomenų dalis.
Antrasis klausimas, kurį reikia apsvarstyti, nors ir akivaizdu, yra tai, kad paskirties vietos dekoderis turi žinoti, kaip pateikiama jį pasiekianti informacija. Tekste yra simbolių, kurie nepriklauso rinkiniui ASCII galima spausdinti (nuo 32 iki 126), pavyzdžiui, raidės su akcentu. Arduino naudos du baitus (UTF-8), kad pavaizduotų šiuos simbolius. Įprasto negalima tiesiog naudoti \0
kaip teksto terminą, nes daugeliu atvejų pirmasis baitas, su kuriuo pavaizduotas simbolis, bus tiksliai nulis.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#include “base64.h”
char texto_prueba[]=“La bella y graciosa moza marchose a lavar la ropa.\nLa mojó en el arroyuelo y cantando la lavó.\nLa frotó sobre una piedra, la colgó de un abedul.\nDespués de lavar la ropa, la niña se fue al mercado.\nUn pastor vendía ovejas pregonando a viva voz:\nved qué oveja, ved qué lana, ved qué bestia, qué animal.\nLa niña la vio muy flaca, sin embargo le gustó.\nYo te pago veinte escudos y no discutamos más.\nVuelve la niña cantando muy contenta con su oveja.\nCuando llegaron al bosque la ovejita se escapó.\nLa niña desesperada arrojose encima de ella.\nVelozmente y con destreza aferrola por detrás.\nLlegaba por el camino jinete de altivo porte.\nDescendió de su caballo y a la niña le cantó…~”;
char *resultado;
Base64 base64;
void setup()
{
Serial.begin(9600);
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) // ¿Es un Arduino Leonardo (ATmega32U4)?
while(!Serial){}; // Esperar a Arduino Leonardo
#endif
// Mostrar el texto original
unsigned int contador=0;
while(texto_prueba[contador]!=‘~’)
{
//Serial.println(String(texto_prueba[contador])+”=”+String(texto_prueba[contador],DEC));
Serial.print(String(texto_prueba[contador]));
contador++;
}
Serial.println(“\n”);
// Mostrar el texto codificado en Base64
contador=0;
while(texto_prueba[contador]!=‘~’)
{
resultado=base64.convertir(texto_prueba[contador],texto_prueba[contador+1]==‘~’);
byte contador_resultado=0;
while(resultado[contador_resultado]>0)
{
Serial.print(String(resultado[contador_resultado]));
contador_resultado++;
}
contador++;
}
}
void loop()
{
}
|
Ankstesnio pavyzdžio 26 eilutėje parodytas naudojimas biblioteka, skirta Arduino koduoti Base64. Būtina tik nurodyti metodą convertir
kiekvieną baitą, kurį norite užkoduoti, ir pasirinktinai ar tai paskutinis, arba, jei ne, sustabdyti konvertavimą naudojant metodą terminar
kai pasieksi pabaigą.
Kaip matyti toliau pateiktoje ekrano kopijoje, pavyzdinė programa biblioteka, skirta Arduino koduoti Base64 pirmiausia rodomas tekstas, kuriame bus užkoduotas Pagrindas64, šiuo atveju – garsiosios milžinų dainos pradžia Les Luthiers, o vėliau ir kodavimo rezultatas Pagrindas64 naudojant formato eilutės ilgį Mime.
Rašyti komentarą