Is het mogelijk om een ​​bestand met base64 te coderen in chunks?

Ik probeer een groot invoerbestand te baseren64 en een tekstuitvoerbestand te maken, en ik probeer uit te vinden of het mogelijk is om het invoerbestand bit voor bit te coderen, of dat ik het hele bestand moet coderen ding tegelijk.

Dit gebeurt op de AS/400 (iSeries), als dat enig verschil maakt. Ik gebruik mijn eigen base64-coderingsroutine (geschreven in RPG) die uitstekend werkt, en als het geen klein formaat betreft, zou het goed zijn.

12

3 antwoord

Het is niet mogelijk bit-by-bit maar 3 bytes per keer, of veelvouden van 3 bytes op tijd zullen doen !.

Met andere woorden, als u uw invoerbestand opsplitst in "chunks" welke maat (en) een veelvoud is van 3 bytes, dan kunt u de chunks afzonderlijk coderen en de resulterende B64-gecodeerde stukken samenvoegen (in de overeenkomstige volgorde, van Houd er rekening mee dat de laatste chuink niet exact een veelvoud van 3 bytes hoeft te zijn, afhankelijk van de modulo 3-waarde van de grootte heeft de bijbehorende B64-waarde enkele van deze padding-tekens (meestal het gelijkteken) maar dat is goed , omdat dit het enige stuk is dat zo'n opvulling heeft (en nodig heeft).

In de decoderingsrichting is dit hetzelfde idee, behalve dat u de B64-gecodeerde gegevens in veelvouden van 4 bytes moet splitsen. Decodeer ze parallel/individueel naar wens en reproduceer de originele gegevens door de gedecodeerde delen bij elkaar te voegen (opnieuw in dezelfde volgorde).

Voorbeeld:

"File" contents = "Never argue with the data." (Jimmy Neutron).
Straight encoding = Ik5ldmVyIGFyZ3VlIHdpdGggdGhlIGRhdGEuIiAoSmltbXkgTmV1dHJvbik=

Now, in chunks:
"Never argue     -->     Ik5ldmVyIGFyZ3Vl
with the         -->        IHdpdGggdGhl
data." (Jimmy Neutron) --> IGRhdGEuIiAoSmltbXkgTmV1dHJvbik=

Als je het stuk in die volgorde ziet, zijn de 3 gecodeerde chunks hetzelfde als de code die voor het hele bestand is geproduceerd.

Het decoderen gebeurt op dezelfde manier, met willekeurige chuncked-grootte, op voorwaarde dat het een veelvoud van 4 bytes is. Het is absoluut niet nodig om enige vorm van overeenstemming te hebben tussen de formaten die worden gebruikt voor codering. (hoewel het standaardiseren van één enkele grootte voor elke richting (zeg 300 en 400) de zaken misschien uniformer en gemakkelijker te beheren maakt.

26
toegevoegd
Zie, ik heb een tijdje rond moeten spitten omdat het vereiste was om een ​​specifieke buffergrootte te gebruiken (die NIET een veelvoud van 3 was). Zodra mijn scheet verdwenen was, veranderde ik gewoon de buffergrootte. Dus echt, ik ben een idioot. En hoewel iedereen de vraag beantwoordt met het voor de hand liggende "Maak de buffergrootte een veelvoud van 3", krijgt u het vinkje, omdat u de eerste was. Bedankt!
toegevoegd de auteur roryhewitt, de bron

Hmmm, als je de base64-conversie zelf hebt geschreven, zou je het voor de hand liggende ding moeten hebben opgemerkt: elke reeks van 3 octetten wordt weergegeven door 4 tekens in base64.

U kunt dus de base64-gegevens splitsen op elk veelvoud van vier tekens, en het is mogelijk om deze chunks terug te zetten naar hun oorspronkelijke bits.

Ik weet niet hoe tekenbestanden en bytebestanden op een AS/400 worden afgehandeld, maar als het beide concepten heeft, zou dit heel eenvoudig moeten zijn.

  • zijn tekstbestanden beperkt in de lengte van elke regel?
  • zijn tekstbestanden lijngeoriënteerd of zijn het gewoon tekenstromen?
  • hoeveel bits heeft één byte?
  • zijn byte-bestanden aan het einde opgevuld, zodat er alleen bestanden kunnen worden gemaakt die hele schijfsectoren overspannen?

Als u al deze vragen kunt beantwoorden, welke precieze problemen heeft u dan nog?

2
toegevoegd
Geen - ik was een idioot :(
toegevoegd de auteur roryhewitt, de bron

Het is een triviale poging om eender wat door een stream in stukjes te splitsen.

Je kunt elk blok bytes probleemloos baseren.

Het probleem dat u tegenkomt is dat, tenzij u specifieke vereisten stelt aan uw chunks (veelvouden van 3 bytes), de sequentie van base64-gecodeerde chunks anders zal zijn dan de daadwerkelijke uitvoer die u wilt.

In C# is dit een (slordige) manier waarop je het lui zou kunnen doen. De uitvoering wordt uitgesteld tot string.Concat wordt aangeroepen, dus je kunt alles doen wat je wilt met de gesplitste reeksen. (Als u dit in LINQPad aansluit, ziet u de uitvoer)

void Main()
{
    var data = "lorum ipsum etc lol this is an example!!";
    var bytes = Encoding.ASCII.GetBytes(data);
    var testFinal = Convert.ToBase64String(bytes);

    var chunkedBytes = bytes.Chunk(3);
    var base64chunks = chunkedBytes.Select(i => Convert.ToBase64String(i.ToArray()));
    var final = string.Concat(base64chunks);

    testFinal.Dump(); //uitgang
    final.Dump(); //uitgang
}
public static class Extensions
{
    public static IEnumerable> Chunk(this IEnumerable list, int chunkSize)
    {
        while(list.Take(1).Count() > 0)
        {
            yield return list.Take(chunkSize);
            list = list.Skip(chunkSize);
        }
    }
}

uitgang

bG9ydW0gaXBzdW0gZXRjIGxvbCB0aGlzIGlzIGFuIGV4YW1wbGUhIQ==
bG9ydW0gaXBzdW0gZXRjIGxvbCB0aGlzIGlzIGFuIGV4YW1wbGUhIQ==
2
toegevoegd