added support for binary files
This commit is contained in:
parent
954ca48904
commit
ef0e619642
4 changed files with 58 additions and 21 deletions
10
README.md
10
README.md
|
|
@ -2,14 +2,20 @@
|
||||||
|
|
||||||
Hides a string inside the least significant bit (LSB) of all colors of each pixel.
|
Hides a string inside the least significant bit (LSB) of all colors of each pixel.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```
|
||||||
|
go build -o stego stego.go
|
||||||
|
```
|
||||||
|
|
||||||
## Hide
|
## Hide
|
||||||
|
|
||||||
```
|
```
|
||||||
./stego -in testdata/lenna.png -out testdata/stego.png -secret "hello world!"
|
./stego -in testdata/lenna.png -secret testdata/lenna_256.png -out testdata/stego.png
|
||||||
```
|
```
|
||||||
|
|
||||||
## Reveal
|
## Reveal
|
||||||
|
|
||||||
```
|
```
|
||||||
./stego -in testdata/stego.png
|
./stego -in testdata/stego.png -out lenna_256.png
|
||||||
```
|
```
|
||||||
|
|
|
||||||
69
stego.go
69
stego.go
|
|
@ -3,6 +3,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -11,23 +12,49 @@ import (
|
||||||
_ "image/gif"
|
_ "image/gif"
|
||||||
_ "image/jpeg"
|
_ "image/jpeg"
|
||||||
"image/png"
|
"image/png"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const offset = 4
|
||||||
|
|
||||||
|
func encodeLen(l int) []byte {
|
||||||
|
b := make([]byte, offset)
|
||||||
|
binary.LittleEndian.PutUint32(b, uint32(l))
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLen(p image.Image) int {
|
||||||
|
z := make([]byte, offset)
|
||||||
|
for i := 0; i < offset; i++ {
|
||||||
|
pix := color.NRGBAModel.Convert(p.At(i, 0)).(color.NRGBA)
|
||||||
|
z[i] = (pix.R << 6)
|
||||||
|
z[i] |= (pix.G << 6) >> 2
|
||||||
|
z[i] |= (pix.B << 6) >> 4
|
||||||
|
z[i] |= (pix.A << 6) >> 6
|
||||||
|
}
|
||||||
|
return int(binary.LittleEndian.Uint32(z))
|
||||||
|
}
|
||||||
|
|
||||||
func unseal(p image.Image) (b []byte) {
|
func unseal(p image.Image) (b []byte) {
|
||||||
rect := p.Bounds()
|
rect := p.Bounds()
|
||||||
|
l := getLen(p)
|
||||||
|
c := 0
|
||||||
for i := 0; i < rect.Max.Y; i++ {
|
for i := 0; i < rect.Max.Y; i++ {
|
||||||
for j := 0; j < rect.Max.X; j++ {
|
for j := 0; j < rect.Max.X; j++ {
|
||||||
|
if i == 0 && j == 0 {
|
||||||
|
j = offset
|
||||||
|
}
|
||||||
pix := color.NRGBAModel.Convert(p.At(j, i)).(color.NRGBA)
|
pix := color.NRGBAModel.Convert(p.At(j, i)).(color.NRGBA)
|
||||||
z := (pix.R << 6)
|
z := (pix.R << 6)
|
||||||
z |= (pix.G << 6) >> 2
|
z |= (pix.G << 6) >> 2
|
||||||
z |= (pix.B << 6) >> 4
|
z |= (pix.B << 6) >> 4
|
||||||
z |= (pix.A << 6) >> 6
|
z |= (pix.A << 6) >> 6
|
||||||
if z == byte(0) {
|
if c == l {
|
||||||
b = append(b, '\n')
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b = append(b, z)
|
b = append(b, z)
|
||||||
|
c++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
@ -37,28 +64,22 @@ func seal(p image.Image, s []byte) (image.Image, error) {
|
||||||
rect := p.Bounds()
|
rect := p.Bounds()
|
||||||
n := image.NewNRGBA(rect)
|
n := image.NewNRGBA(rect)
|
||||||
c := 0
|
c := 0
|
||||||
max := (rect.Max.Y * rect.Max.X) - 1
|
arr := append(encodeLen(len(s)), s...)
|
||||||
if len(s) > max {
|
l := len(arr)
|
||||||
|
max := (rect.Max.Y * rect.Max.X)
|
||||||
|
if l > max {
|
||||||
return nil, errors.New("not enough space in image")
|
return nil, errors.New("not enough space in image")
|
||||||
}
|
}
|
||||||
for i := 0; i < rect.Max.Y; i++ {
|
for i := 0; i < rect.Max.Y; i++ {
|
||||||
for j := 0; j < rect.Max.X; j++ {
|
for j := 0; j < rect.Max.X; j++ {
|
||||||
pix := color.NRGBAModel.Convert(p.At(j, i)).(color.NRGBA)
|
pix := color.NRGBAModel.Convert(p.At(j, i)).(color.NRGBA)
|
||||||
if c < len(s) {
|
if c < l {
|
||||||
r := (pix.R &^ 3) | (s[c] >> 6)
|
r := (pix.R &^ 3) | (arr[c] >> 6)
|
||||||
g := (pix.G &^ 3) | (s[c]<<2)>>6
|
g := (pix.G &^ 3) | (arr[c]<<2)>>6
|
||||||
b := (pix.B &^ 3) | (s[c]<<4)>>6
|
b := (pix.B &^ 3) | (arr[c]<<4)>>6
|
||||||
a := (pix.A &^ 3) | (s[c]<<6)>>6
|
a := (pix.A &^ 3) | (arr[c]<<6)>>6
|
||||||
n.Set(j, i, color.NRGBA{r, g, b, a})
|
n.Set(j, i, color.NRGBA{r, g, b, a})
|
||||||
c++
|
c++
|
||||||
} else if c == len(s) {
|
|
||||||
n.Set(j, i, color.NRGBA{
|
|
||||||
pix.R &^ 3,
|
|
||||||
pix.G &^ 3,
|
|
||||||
pix.B &^ 3,
|
|
||||||
pix.A &^ 3,
|
|
||||||
})
|
|
||||||
c++
|
|
||||||
} else {
|
} else {
|
||||||
n.Set(j, i, pix)
|
n.Set(j, i, pix)
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +102,7 @@ func errf(err error) {
|
||||||
func main() {
|
func main() {
|
||||||
flag.StringVar(&inFile, "in", "-", "input file (default: stdin)")
|
flag.StringVar(&inFile, "in", "-", "input file (default: stdin)")
|
||||||
flag.StringVar(&outFile, "out", "-", "output file, always png (default: stdout)")
|
flag.StringVar(&outFile, "out", "-", "output file, always png (default: stdout)")
|
||||||
flag.StringVar(&secret, "secret", "", "secret to hide")
|
flag.StringVar(&secret, "secret", "", "secret file to hide")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
|
@ -94,12 +115,22 @@ func main() {
|
||||||
errf(err)
|
errf(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if outFile != "-" {
|
||||||
|
out, err = os.OpenFile(outFile, os.O_RDWR|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
errf(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
p, _, err := image.Decode(in)
|
p, _, err := image.Decode(in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errf(err)
|
errf(err)
|
||||||
}
|
}
|
||||||
if secret != "" {
|
if secret != "" {
|
||||||
n, err := seal(p, []byte(secret))
|
b, err := ioutil.ReadFile(secret)
|
||||||
|
if err != nil {
|
||||||
|
errf(err)
|
||||||
|
}
|
||||||
|
n, err := seal(p, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errf(err)
|
errf(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
testdata/lenna_256.png
vendored
Normal file
BIN
testdata/lenna_256.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 135 KiB |
BIN
testdata/stego.png
vendored
BIN
testdata/stego.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 560 KiB After Width: | Height: | Size: 590 KiB |
Loading…
Add table
Add a link
Reference in a new issue