镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

buffer.write(buffer, 'base64') #11866

Closed
Closed

Description

@jorangreef

What's the fastest way to convert a buffer containing base64-encoded data to a buffer containing binary data?

Something like this?

var base64Buffer = ...; // e.g. A buffer containing base64 provided by a mime decoder.
var binaryBuffer = new Buffer(base64Buffer.toString('ascii'), 'base64')

Is there a way to write the base64 buffer directly into another buffer, without creating any interim strings?

I thought of binaryBuffer.write(base64Buffer, 'base64') but write() only accepts strings.

Activity

  1. added
    bufferIssues and PRs related to the buffer subsystem.
    questionIssues asking questions about Node.js.
    on Mar 15, 2017
  2. seishun commented on Mar 15, 2017

    @seishun
    Contributor

    @jorangreef There's always going to be an interim string, since you have to first "decode" ASCII by going from Buffer to string, then decode base64 by going from string to Buffer.

    Your first snippet is fine, but I'd recommend using the new API: Buffer.from(base64Buffer.toString(), 'base64')

  3. mscdex commented on Mar 15, 2017

    @mscdex
    Contributor

    @seishun I think he means without creating a V8 String object. It's entirely possible, it's just not something that's currently available AFAIK.

  4. targos commented on Mar 15, 2017

    @targos
    Member

    This is partly available in the buffer.transcode API, but base64 encoding is not supported.

  5. seishun commented on Mar 15, 2017

    @seishun
    Contributor

    This is partly available in the buffer.transcode API, but base64 encoding is not supported.

    Because it uses ICU, and base64 isn't a way to encode text as binary data, it's the other way around. IMO supporting it in buffer.transcode would be kind of confusing.

  6. jasnell commented on Mar 15, 2017

    @jasnell
    Member

    buffer.transcode() intentionally only deals with efficient conversion of char sets. It does not deal with transformations like hex or base64 and never should.

  7. jorangreef commented on Mar 16, 2017

    @jorangreef
    ContributorAuthor

    Your first snippet is fine, but I'd recommend using the new API: Buffer.from(base64Buffer.toString(), 'base64')

    @seishun thanks, using the constructor was a typo from habit.

    I think he means without creating a V8 String object. It's entirely possible, it's just not something that's currently available AFAIK.

    @mscdex yes, that's what I was getting at, avoiding the String allocation. It should be possible, but not provided by the api currently.

    buffer.transcode() intentionally only deals with efficient conversion of char sets. It does not deal with transformations like hex or base64 and never should.

    @jasnell agreed, hence the suggestion for buffer.write(buffer, 'base64') or another alternative. I don't think transcode is the way to do it.

  8. seishun commented on Mar 16, 2017

    @seishun
    Contributor

    buffer.write(buffer, 'base64') would be pretty confusing too. You're writing a buffer into a buffer, yet there's an encoding argument.

  9. jasnell commented on Mar 16, 2017

    @jasnell
    Member

    to be honest, I'd like to see a revision to Hex and Base64 support in the APIs because things are fairly inconsistent as they are now (e.g. Buffer.from([...]).toString('utf8') does not actually convert the bytes to utf8 but Buffer.from[...]).toString('hex') does convert to hex).

    What would be more correct would be something like:

    Buffer.from([...]).encode('base64');
    Buffer.from([...]).encode('hex');

    Unfortunately toString('base64') is one of the most common uses of Buffer in the ecosystem so this is likely something that can never actually change.

  10. addaleax commented on Mar 16, 2017

    @addaleax
    Member

    I agree, it’s been bugging me since I started node that toString('utf8') decodes from UTF-8 and toString('hex') encodes as Hex. If somebody has a good idea for how to tackle that wrt our API I’d love to see it. :)

  11. seishun commented on Mar 16, 2017

    @seishun
    Contributor

    I agree it's confusing, but on the other hand, toString(enc) just says "convert to string using enc" which makes sense for both hex and UTF-8.

  12. jasnell commented on Mar 16, 2017

    @jasnell
    Member

    @addaleax ... A require('buffer').encode(buf, 'hex') and require('buffer').encode(buf, 'base64') could easily deal with the discrepancy and would pair nicely with require('buffer').transcode(). The return value would be another Buffer with the encoded bytes. Introducing a new API that makes more sense is not really the difficult issue, however. It's transitioning people off the existing buf.toString('hex') and buf.toString('base64') that's the real difficulty.

    Buffer creation is equally problematic. Buffer.from(bytes, 'utf8') and Buffer.from(bytes, 'hex') are quite different from one another. The inconsistency is irritating and better APIs could certainly help but getting userland to actually use those improved APIs has been a huge difficulty.

  13. seishun commented on Mar 16, 2017

    @seishun
    Contributor

    @jasnell I'd be against adding new APIs unless we are also planning to phase out the old ones, and we know well that it's not as easy as we'd wish. And the existing API isn't exactly bad either.

  14. jasnell commented on Mar 16, 2017

    @jasnell
    Member

    Yep, which is why I haven't pursued it. The current API is not painful enough to justify the level of disruption changing it would cause.

  15. addaleax commented on Mar 20, 2017

    @addaleax
    Member

    Can this be closed as an answered question? All the ways currently exposed by Node use an temporary string, and that makes sense, because as @seishun explained this question is really asking about base64+ascii “double” encoding.

  16. seishun commented on Mar 20, 2017

    @seishun
    Contributor

    Indeed, closing as an answered question.

  17. jorangreef commented on Apr 3, 2017

    @jorangreef
    ContributorAuthor

    In case anyone has an issue with the lack of buffer-to-buffer Base64 encoding/decoding support in Node, I just finished https://github.com/ronomon/base64 as a stop-gap until these and other base64 issues are addressed. The encoder/decoder accepts and returns buffers without allocating any interim V8 Strings. The throughput gain from avoiding unnecessary string allocation is substantial over 4 MB+ buffers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bufferIssues and PRs related to the buffer subsystem.questionIssues asking questions about Node.js.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions