1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-05-20 00:18:12 +08:00
Files
kubo/core/commands/multibase.go
2022-10-06 10:18:40 -04:00

172 lines
4.5 KiB
Go

package commands
import (
"bytes"
"fmt"
"io"
"strings"
cmds "github.com/ipfs/go-ipfs-cmds"
"github.com/ipfs/kubo/core/commands/cmdenv"
mbase "github.com/multiformats/go-multibase"
)
var MbaseCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Encode and decode files or stdin with multibase format",
},
Subcommands: map[string]*cmds.Command{
"encode": mbaseEncodeCmd,
"decode": mbaseDecodeCmd,
"transcode": mbaseTranscodeCmd,
"list": basesCmd,
},
Extra: CreateCmdExtras(SetDoesNotUseRepo(true)),
}
const (
mbaseOptionName = "b"
)
var mbaseEncodeCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Encode data into multibase string",
LongDescription: `
This command expects a file name or data provided via stdin.
By default it will use URL-safe base64url encoding,
but one can customize used base with -b:
> echo hello | ipfs multibase encode -b base16 > output_file
> cat output_file
f68656c6c6f0a
> echo hello > input_file
> ipfs multibase encode -b base16 input_file
f68656c6c6f0a
`,
},
Arguments: []cmds.Argument{
cmds.FileArg("file", true, false, "data to encode").EnableStdin(),
},
Options: []cmds.Option{
cmds.StringOption(mbaseOptionName, "multibase encoding").WithDefault("base64url"),
},
Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error {
if err := req.ParseBodyArgs(); err != nil {
return err
}
encoderName, _ := req.Options[mbaseOptionName].(string)
encoder, err := mbase.EncoderByName(encoderName)
if err != nil {
return err
}
files := req.Files.Entries()
file, err := cmdenv.GetFileArg(files)
if err != nil {
return fmt.Errorf("failed to access file: %w", err)
}
buf, err := io.ReadAll(file)
if err != nil {
return fmt.Errorf("failed to read file contents: %w", err)
}
encoded := encoder.Encode(buf)
reader := strings.NewReader(encoded)
return resp.Emit(reader)
},
}
var mbaseDecodeCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Decode multibase string",
LongDescription: `
This command expects multibase inside of a file or via stdin:
> echo -n hello | ipfs multibase encode -b base16 > file
> cat file
f68656c6c6f
> ipfs multibase decode file
hello
> cat file | ipfs multibase decode
hello
`,
},
Arguments: []cmds.Argument{
cmds.FileArg("encoded_file", true, false, "encoded data to decode").EnableStdin(),
},
Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error {
if err := req.ParseBodyArgs(); err != nil {
return err
}
files := req.Files.Entries()
file, err := cmdenv.GetFileArg(files)
if err != nil {
return fmt.Errorf("failed to access file: %w", err)
}
encodedData, err := io.ReadAll(file)
if err != nil {
return fmt.Errorf("failed to read file contents: %w", err)
}
_, data, err := mbase.Decode(string(encodedData))
if err != nil {
return fmt.Errorf("failed to decode multibase: %w", err)
}
reader := bytes.NewReader(data)
return resp.Emit(reader)
},
}
var mbaseTranscodeCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Transcode multibase string between bases",
LongDescription: `
This command expects multibase inside of a file or via stdin.
By default it will use URL-safe base64url encoding,
but one can customize used base with -b:
> echo -n hello | ipfs multibase encode > file
> cat file
uaGVsbG8
> ipfs multibase transcode file -b base16 > transcoded_file
> cat transcoded_file
f68656c6c6f
`,
},
Arguments: []cmds.Argument{
cmds.FileArg("encoded_file", true, false, "encoded data to decode").EnableStdin(),
},
Options: []cmds.Option{
cmds.StringOption(mbaseOptionName, "multibase encoding").WithDefault("base64url"),
},
Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error {
if err := req.ParseBodyArgs(); err != nil {
return err
}
encoderName, _ := req.Options[mbaseOptionName].(string)
encoder, err := mbase.EncoderByName(encoderName)
if err != nil {
return err
}
files := req.Files.Entries()
file, err := cmdenv.GetFileArg(files)
if err != nil {
return fmt.Errorf("failed to access file: %w", err)
}
encodedData, err := io.ReadAll(file)
if err != nil {
return fmt.Errorf("failed to read file contents: %w", err)
}
_, data, err := mbase.Decode(string(encodedData))
if err != nil {
return fmt.Errorf("failed to decode multibase: %w", err)
}
encoded := encoder.Encode(data)
reader := strings.NewReader(encoded)
return resp.Emit(reader)
},
}