-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
151 lines (135 loc) · 3.85 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright (c) 2023, Lucas Menendez <[email protected]>
// See LICENSE for licensing information
package main
import (
"fmt"
"os"
"strconv"
"github.com/lucasmenendez/gosteganography/image"
)
var helpMessage = `
GoSteganography CLI helps to you to hide a message in a PNG image and unhide it
from the output.
Usage:
gosteganography <command> [arguments]
The commands are:
hide Hides the content of the secret file in a new copy of input image.
unhide Recovers the content of the secret from the input image.
`
var hideMessage = `
usage: gosteganography hide [input image] [secret file] [output image]
Hide command hides the provided message in the current Image. Before modify the
image pixels, it checks if the provided message exceeds the maximun number of
bytes that the Image can hide safely. If the limit is not exceeded, it encodes
the message in its binary representation and hides it in the Image pixels.
`
var unhideMessage = `
usage: gosteganography unhide [input image] [secret file] [number of bits]
Unhide function writes the hidden message from the image provided using the
number of bits provided. If the number of bits in the hidden message is not
correct, the result will be wrong (truncated or badly formatted).
`
func main() {
if len(os.Args) < 2 {
fmt.Println("no command provided")
fmt.Println(helpMessage)
return
}
switch cmd, args := os.Args[1], os.Args[2:]; cmd {
case "help":
fmt.Println(helpMessage)
case "hide":
if err := hide(args...); err != nil {
fmt.Println(err)
fmt.Println(hideMessage)
}
case "unhide":
if err := unhide(args...); err != nil {
fmt.Println(err)
fmt.Println(unhideMessage)
}
default:
fmt.Println("unknown command")
fmt.Println(helpMessage)
}
}
func hide(args ...string) error {
// parse args
switch {
case len(args) == 0 || args[0] == "help":
fmt.Println(hideMessage)
return nil
case len(args) != 3:
return fmt.Errorf("bad arguments")
default:
input, message, output := args[0], args[1], args[2]
// open input image
inputFd, err := os.Open(input)
if err != nil {
return fmt.Errorf("error opening input image: %w", err)
}
defer inputFd.Close()
// reading message file content
secretMessage, err := os.ReadFile(message)
if err != nil {
return fmt.Errorf("error reading message file: %w", err)
}
// reading image from imput file
img, err := image.Read(inputFd)
if err != nil {
return err
}
// hide message conntent and gets the number of bits written
nbits, err := img.Hide(secretMessage)
if err != nil {
return err
}
// create output image file
outputFd, err := os.Create(output)
if err != nil {
return fmt.Errorf("error creating output image file: %w", err)
}
defer outputFd.Close()
// wirte the output image in the created file
if err := img.Write(outputFd); err != nil {
return fmt.Errorf("error writting output image file: %w", err)
}
// print the number of bits written
fmt.Println("bits written: ", nbits)
return nil
}
}
func unhide(args ...string) error {
// parse args
switch {
case len(args) == 0 || args[0] == "help":
fmt.Println(unhideMessage)
return nil
case len(args) != 3:
return fmt.Errorf("bad arguments")
default:
input, message := args[0], args[1]
nbits, err := strconv.Atoi(args[2])
if err != nil {
return fmt.Errorf("requires a valid number of bits")
}
// open input image
inputFd, err := os.Open(input)
if err != nil {
return fmt.Errorf("error opening input image: %w", err)
}
defer inputFd.Close()
// reading image from imput file
img, err := image.Read(inputFd)
if err != nil {
return err
}
// retrieve the message content from the image
secretMessage := img.Unhide(nbits)
// write in the message file
if err := os.WriteFile(message, secretMessage, os.ModePerm); err != nil {
return fmt.Errorf("error writting message file: %w", err)
}
return nil
}
}