github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/qrcode/qrcode.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package qrcode
     5  
     6  import (
     7  	"bytes"
     8  	"strings"
     9  
    10  	"rsc.io/qr"
    11  )
    12  
    13  // Encodings is the result of QR encoding.  It has three different
    14  // representations:  Terminal with ansi codes, PNG-encoded bytes,
    15  // and ASCII string where "#" is black and " " is white.
    16  type Encodings struct {
    17  	Terminal string
    18  	PNG      []byte
    19  	ASCII    string
    20  }
    21  
    22  // Encode makes a QR code out of data and encodes it into three
    23  // different representations.
    24  func Encode(data []byte) (*Encodings, error) {
    25  	code, err := qr.Encode(string(data), qr.L)
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  
    30  	var result Encodings
    31  	result.PNG = code.PNG()
    32  	result.Terminal = terminal(code)
    33  	result.ASCII = ascii(code)
    34  
    35  	return &result, nil
    36  }
    37  
    38  const (
    39  	black = "\033[40m  \033[0m"
    40  	white = "\033[47m  \033[0m"
    41  )
    42  
    43  func terminal(code *qr.Code) string {
    44  	var buf bytes.Buffer
    45  
    46  	line := strings.Repeat(white, code.Size+2)
    47  	buf.WriteString(line + "\n")
    48  	for row := 0; row < code.Size; row++ {
    49  		buf.WriteString(white)
    50  		for col := 0; col < code.Size; col++ {
    51  			if code.Black(col, row) {
    52  				buf.WriteString(black)
    53  			} else {
    54  				buf.WriteString(white)
    55  			}
    56  		}
    57  		buf.WriteString(white + "\n")
    58  	}
    59  	buf.WriteString(line + "\n")
    60  
    61  	return buf.String()
    62  }
    63  
    64  func ascii(code *qr.Code) string {
    65  	var buf bytes.Buffer
    66  
    67  	buf.WriteString("\n")
    68  	for row := 0; row < code.Size; row++ {
    69  		buf.WriteString(" ")
    70  		for col := 0; col < code.Size; col++ {
    71  			if code.Black(col, row) {
    72  				buf.WriteString("#")
    73  			} else {
    74  				buf.WriteString(" ")
    75  			}
    76  		}
    77  		buf.WriteString("\n")
    78  	}
    79  	buf.WriteString("\n")
    80  
    81  	return buf.String()
    82  }