Open kokoichi206 opened 2 years ago
data := binary.BigEndian.Uint32(append(make([]byte, 1), buf...))
// fmt.Println(binary.LittleEndian.Uint32(append(make([]byte, 1), buf...)))
data := int(buf[2]) + int(buf[1])*256 + int(buf[0])*256*256
インデックスだとマルチバイト時にどこを指すのかが曖昧なため?
hoge := "hogee"
fmt.Println(string(hoge[0]))
// 104 が出力される
a だけ書かれたファイルを読み取った時の buf
[97 0 0]
abcd が書かれたファイルを loop で読み取った時の buf 出力
[97 98 99]
[100 98 99]
3 byte にみたない時は前回の値が消えてないので強制的に消してあげる
名前をつけてそこを参照しにいく
func ReadAll() {
...
main:
for {
v, _ := r.Read(buf)
switch v {
case 0:
break main
case 1:
buf[1] = 0
}
}
fmt.Println(buf)
}
func readStandardInput() []byte {
scanner := bufio.NewScanner(os.Stdin)
// 1行分スキャン
scanner.Scan()
return scanner.Bytes()
}
// ファイルからの読み込みと標準入力からの入力のどちらかで関数を実行する。
func execute(fn func([]byte) string, file []byte, si []byte) string {
if len(file) != 0 {
return fn(file)
}
return fn(si)
}
EOF が来るまでは確定で 3byte 読み込める想定だったが、どうやらそうではない。。。 例えば jpg だと 1366 * 3byte ごとに、3 byte ちょうどで読み込めてない。
5000 bytes ごとになんかある??
1365
2731
4097
5463
6829
...
全部読み込んでから、3 byte ずつ使うようにしたらいけた。。。
f, err := os.Open("43694.jpg")
// f, err := os.Open("test.txt")
if err != nil {
return
}
defer f.Close()
r := bufio.NewReader(f)
// 3 bytes ずつ読み込む(24 bits -> 4*6 bits ずつエンコードするため)
buf := make([]byte, 3)
var builder strings.Builder
cnt := 0
READLOOP:
for {
v, err := r.Read(buf)
// if err != nil {
// fmt.Println(err)
// }
switch v {
case 0:
break READLOOP
case 1:
buf[1] = 0
buf[2] = 0
// fmt.Println(cnt)
case 2:
buf[2] = 0
// fmt.Println(cnt)
}
if e := encode3bytes(buf, v, &builder, err); e != nil {
fmt.Println("unexpected error occured while encoding")
return
}
cnt += 1
}
fmt.Println(builder.String())
wiki
ヌル終端文字列(ヌルしゅうたんもじれつ、英語: null-terminated string)とは、文字を配列に格納し、ヌル文字('\0'、ASCIIコードではNUL)でその終端(番兵)を表した文字列である
// 渡されたバイト列ををデコードする。
func Decode(buf []byte) string {
sb := string(buf)
max := len(sb) / 4
var res bytes.Buffer
// 最終行以外をエンコード。
for i := 0; i < max; i++ {
b := sb[4*i : 4*i+4]
data := alphabetMap[string(b[3])] + alphabetMap[string(b[2])]*64 + alphabetMap[string(b[1])]*64*64 + alphabetMap[string(b[0])]*64*64*64
b1 := data / (256 * 256)
b2 := (data % (256 * 256)) / 256
b3 := data % 256
res.Write([]byte{byte(b1), byte(b2), byte(b3)})
}
return res.String()
}
$ diff <(base64 -d encoded_test.txt) <(./base64 -d encoded_test.txt)
Binary files /dev/fd/15 and /dev/fd/16 differ
jpg にはいっぱい隠れてる。
以下のようにして、test_data/cat.jpg
に隠れてる NULL を探すと 1636 個あった!
(前あった問題と同じかも。。。)
func readFile(fileName string) []byte {
buf, err := ioutil.ReadFile(fileName)
if err != nil {
fmt.Printf("Unable to open '%s': No such file or directory", fileName)
os.Exit(1)
}
cnt := 0
for _, b := range buf {
if b == 0 {
cnt += 1
}
}
fmt.Printf("found NULL string %d\n", cnt)
return buf
}
途中に見つかる NULL 文字は、元のデータ形式によっては十分あり得るので保持。 ただし、最終デコードが NULL(byte の値が 0)であることは、もともとのバイトが 3 なかったことを意味しているので、そこはデコードさせない。
Logic- RFC4648
6 bit -> 8 bit の1文字に変換するので、33 % は増える(パディングもそれに追加)
仕様
基本は mac に入っている base64 に合わせる
2 つ以上のファイル名が渡されたとき
1 つめのファイルのエンコードの値のみが出力される