I have a long string
from Base64
, but it is too long, how can I covert it to a short one. And I want it is a reversible operation, as I want to get the long one from the short one.
By the way, I do not want to save these two strings to database.

- 4,795
- 2
- 24
- 33

- 605
- 8
- 20
-
1You can try to un-base64 + zip + base64 it again. – zerkms Aug 06 '21 at 03:21
-
5As @zerkms commented, you'll have to find a compression algorithm (gzip, zip, etc) to compress it. However compression worsens as data becomes more random, so I'd suggest you run gzip/zip first, then take the base64 of that. – German Aug 06 '21 at 03:55
-
1base64 is very inefficient. avoid it if you can, storing data in binary format if possible – erik258 Aug 06 '21 at 04:41
-
3@DanielFarrell "is very inefficient" --- efficiency is not an absolute property. Nothing is absolutely "very inefficient" and vice versa. You can compare it though with something else under some constraints. – zerkms Aug 06 '21 at 04:51
-
2Base64 encoding produces 1 char (8 bits) for every 6bits of input data, thus has an overhead of 33%. @Yongqi Z can you confirm that you want to avoid this overhead, e.g. by storing an original decoded string of exactly 300 bytes instead of the Base64 encoded version of exactly 400 bytes? – Deleplace Aug 06 '21 at 10:04
-
1@zerkms that's not gonna work. There are always some data that cannot be compressed: [Why does zipping a zipped file not reduce its size?](https://superuser.com/a/772869/241386) – phuclv Aug 06 '21 at 12:44
-
1[base85](https://en.wikipedia.org/wiki/Ascii85), [base91](http://base91.sourceforge.net/) and base122 are much better than base64, although of course still far worse than storing directly as binary. [What is the most efficient binary to text encoding?](https://stackoverflow.com/a/49861826/995714) – phuclv Aug 06 '21 at 12:47
-
@phuclv I didn't say it would work in 100%, I suggested them to try and see if it works in their very case. – zerkms Aug 07 '21 at 00:38
-
I have tried gzip, but I find the string is not changed to shorter. codes: `var b bytes.Buffer gz := gzip.NewWriter(&b) gz.Write([]byte("helloworldhelloworldhelloworld")) fmt.Println(b.Bytes())` result: `[31 139 8 0 0 0 0 0 0 255 202 72 205 201 201 47 207 47 202 73 193 198 2 4 0 0 255 255 53 217 193 226 30 0 0 0]` – Yongqi Z Aug 09 '21 at 01:50
3 Answers
Converting arbitrary long strings to arbitrary short strings is not possible in general because of the Pigeonhole principle:
- reversibility implies that the conversion codomain (small strings) needs to be have at least as many elements as the conversion domain (large strings),
- there exist vastly more distinct long strings than distinct short strings.
As an analogy with integers, consider that it is not possible to convert a 3-digit number (900 possibilities) into a 2-digit number (90 possibilities) and still be reversible, as 90 < 900.
However, if the long string is predictable and has a lot of redundancy, you may try to apply a lossless compression algorithm like gzip, in order to shorten it in the common case.

- 6,812
- 5
- 28
- 41
-
I may have misunderstood the question, though. I'll add another answer about encoding to/decoding from Base64. – Deleplace Aug 06 '21 at 09:59
-
2[*Lossless data compression algorithms cannot guarantee compression for all input data sets. In other words, for any lossless data compression algorithm, there will be an input data set that does not get smaller when processed by the algorithm, and for any lossless data compression algorithm that makes at least one file smaller, there will be at least one file that it makes larger.*](https://en.wikipedia.org/wiki/Lossless_compression#Limitations) – phuclv Aug 06 '21 at 12:45
Base64 encoding and decoding are indeed reversible operations. The decoded string is shorter, so it may be cheaper to transfer and store in some cases (not always, YMMV).
The base64 package in the standard library has everything you need to easily decode the "long" Base64 encoded string into the original decoded string, roughly 25% shorter:
decoded, err := base64.StdEncoding.DecodeString(encoded)
if err != nil {
fmt.Println("error:", err)
}
You can try this in the Playground:
Note that there exists several variants of the Base64 format, so you need to know exactly which one was used to encode, and use the same to decode. base64.StdEncoding
is the variant RFC 4648.

- 6,812
- 5
- 28
- 41
The next code in GoLang worked for me:
package main
import (
"bytes"
"compress/gzip"
"encoding/json"
"io/ioutil"
"net/http"
"github.com/gin-gonic/gin"
)
type User struct {
Name string `json:"name"`
Email string `json:"email"`
}
func main() {
r := gin.Default()
// Endpoint to compress JSON data using GZIP
r.POST("/compress", func(c *gin.Context) {
var user User
if err := c.BindJSON(&user); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "invalid json"})
return
}
jsonData, err := json.Marshal(user)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "json marshalling failed"})
return
}
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
if _, err := gz.Write(jsonData); err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "gzip compression failed"})
return
}
if err := gz.Close(); err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "gzip writer close failed"})
return
}
c.Data(http.StatusOK, "application/octet-stream", buf.Bytes())
})
// Endpoint to decompress GZIP compressed JSON data
r.POST("/decompress", func(c *gin.Context) {
data, err := ioutil.ReadAll(c.Request.Body)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "failed to read request body"})
return
}
var buf bytes.Buffer
buf.Write(data)
gz, err := gzip.NewReader(&buf)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "invalid gzip format"})
return
}
defer gz.Close()
decompressedData, err := ioutil.ReadAll(gz)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "gzip decompression failed"})
return
}
var user User
if err := json.Unmarshal(decompressedData, &user); err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "json unmarshalling failed"})
return
}
c.JSON(http.StatusOK, user)
})
// Run the server
if err := r.Run(":8080"); err != nil {
panic(err)
}
}

- 81
- 1
- 2
- 6