回答編集履歴
8
修正
answer
CHANGED
@@ -23,13 +23,12 @@
|
|
23
23
|
> encoders to add line feeds after a specific number of characters.
|
24
24
|
|
25
25
|
- その結果4のバイト倍数ずつ読み込むと改行コードも4バイトに含まれてしまい、Base64の1セットが崩れてしまう
|
26
|
-
- bufferSizeがファイルより大きい場合は改行コードも合わせてデコード出来るので問題ない(base64_decode()が上手く判定
|
26
|
+
- bufferSizeがファイルより大きい場合は改行コードも合わせてデコード出来るので問題ない(base64_decode()が上手く判定する)
|
27
27
|
|
28
28
|
|
29
29
|
解決方法
|
30
30
|
---
|
31
|
-
1. 一回の読み込みを76の倍数にする
|
32
|
-
|
31
|
+
1. 一回の読み込みを(76バイト+改行コード)の倍数のバイト数にし改行コードも含めてbase64_decode()に処理させる
|
33
32
|
|
34
33
|
|
35
34
|
ソース
|
7
追記
answer
CHANGED
@@ -2,7 +2,26 @@
|
|
2
2
|
|
3
3
|
原因
|
4
4
|
---
|
5
|
-
-
|
5
|
+
- base64エンコードすると76バイト毎に改行コードが挿入される(Base64の仕様(必須では無いがMIMEの仕様に合わせるためにデフォルトではそうなる実装が多いっぽい?))
|
6
|
+
|
7
|
+
[RFC The Base16, Base32, and Base64 Data Encodings](https://tools.ietf.org/html/rfc4648)
|
8
|
+
|
9
|
+
|
10
|
+
> 3.1. Line Feeds in Encoded Data
|
11
|
+
>
|
12
|
+
> MIME [4] is often used as a reference for base 64 encoding. However,
|
13
|
+
> MIME does not define "base 64" per se, but rather a "base 64 Content-
|
14
|
+
> Transfer-Encoding" for use within MIME. As such, MIME enforces a
|
15
|
+
> limit on line length of base 64-encoded data to 76 characters. MIME
|
16
|
+
> inherits the encoding from Privacy Enhanced Mail (PEM) [3], stating
|
17
|
+
> that it is "virtually identical"; however, PEM uses a line length of
|
18
|
+
> 64 characters. The MIME and PEM limits are both due to limits within
|
19
|
+
> SMTP.
|
20
|
+
>
|
21
|
+
> Implementations MUST NOT add line feeds to base-encoded data unless
|
22
|
+
> the specification referring to this document explicitly directs base
|
23
|
+
> encoders to add line feeds after a specific number of characters.
|
24
|
+
|
6
25
|
- その結果4のバイト倍数ずつ読み込むと改行コードも4バイトに含まれてしまい、Base64の1セットが崩れてしまう
|
7
26
|
- bufferSizeがファイルより大きい場合は改行コードも合わせてデコード出来るので問題ない(base64_decode()が上手く判定している気がする)
|
8
27
|
|
6
追記
answer
CHANGED
@@ -24,6 +24,7 @@
|
|
24
24
|
$readed = 0;
|
25
25
|
if($file = fopen($localFile , 'rb')){
|
26
26
|
//MIMEに合わせて一回で読むバイト数を決め打ち。合計値をn倍してもOK。
|
27
|
+
//ここではエンコード環境がlinuxなので改行コードがLF(1バイト)になっているが、エンコード環境によってはCRLF(2バイト)になるはずなので、扱いたいファイルの仕様に合わせて変更する
|
27
28
|
$bufferSize = 76+strlen(PHP_EOL);
|
28
29
|
while(!feof($file)){
|
29
30
|
$buffer = fread($file, $bufferSize);
|
5
MIMEに対する誤記を修正
answer
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
原因
|
4
4
|
---
|
5
|
-
- zipをbase64エンコードすると76バイト毎に改行コードが挿入される(
|
5
|
+
- zipをbase64エンコードすると76バイト毎に改行コードが挿入される(Base64の仕様(shouldなので必須では無い))
|
6
|
-
- その結果4バイトずつ読み込むと改行コードも4バイトに含まれてしまい、
|
6
|
+
- その結果4のバイト倍数ずつ読み込むと改行コードも4バイトに含まれてしまい、Base64の1セットが崩れてしまう
|
7
7
|
- bufferSizeがファイルより大きい場合は改行コードも合わせてデコード出来るので問題ない(base64_decode()が上手く判定している気がする)
|
8
8
|
|
9
9
|
|
4
修正
answer
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
解決方法
|
11
11
|
---
|
12
12
|
1. 一回の読み込みを76の倍数にする
|
13
|
-
2. 一回の読み込み
|
13
|
+
2. 一回の読み込みを(76バイト+改行コード)の倍数のバイト数にして、改行コードはbase64_decode()に処理させる
|
14
14
|
|
15
15
|
|
16
16
|
ソース
|
3
環境追記
answer
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
興味があったので手元の
|
1
|
+
興味があったので手元のRaspbianで試してみたところ、スマートでは無いですが解決できたので回答します。
|
2
2
|
|
3
3
|
原因
|
4
4
|
---
|
@@ -40,6 +40,16 @@
|
|
40
40
|
検証
|
41
41
|
---
|
42
42
|
|
43
|
+
PHPのバージョン(検証していませんが、PHP5.5でも動くと思う)
|
44
|
+
```bash
|
45
|
+
$ php -v
|
46
|
+
PHP 7.3.11-1~deb10u1 (cli) (built: Oct 26 2019 14:14:18) ( NTS )
|
47
|
+
Copyright (c) 1997-2018 The PHP Group
|
48
|
+
Zend Engine v3.3.11, Copyright (c) 1998-2018 Zend Technologies
|
49
|
+
with Zend OPcache v7.3.11-1~deb10u1, Copyright (c) 1999-2018, by Zend Technologies
|
50
|
+
|
51
|
+
```
|
52
|
+
|
43
53
|
テキストファイルの作成
|
44
54
|
UTF-8で`test.txt`を作成
|
45
55
|
```text
|
2
修正
answer
CHANGED
@@ -47,11 +47,15 @@
|
|
47
47
|
```
|
48
48
|
|
49
49
|
zip化
|
50
|
+
```bash
|
50
|
-
|
51
|
+
$ zip test.zip test.txt
|
51
52
|
adding: test.txt (deflated 38%)`
|
53
|
+
```
|
52
54
|
|
53
55
|
base64dにエンコード
|
56
|
+
```bash
|
54
|
-
|
57
|
+
$ base64 test.zip > test.bat`
|
58
|
+
```
|
55
59
|
|
56
60
|
エンコードされた内容の確認
|
57
61
|
改行コードが入っていることがわかる
|
1
追記
answer
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
|
10
10
|
解決方法
|
11
11
|
---
|
12
|
+
1. 一回の読み込みを76の倍数にする
|
12
|
-
76バイト
|
13
|
+
2. 一回の読み込み辺り、76バイトの倍数+改行コードを含めたバイト数を読み込んで、base64_decode()に処理させる
|
13
14
|
|
14
15
|
|
15
16
|
ソース
|
@@ -22,8 +23,8 @@
|
|
22
23
|
|
23
24
|
$readed = 0;
|
24
25
|
if($file = fopen($localFile , 'rb')){
|
25
|
-
//MIMEに合わせて一回で読むバイト数を決め打ち。
|
26
|
+
//MIMEに合わせて一回で読むバイト数を決め打ち。合計値をn倍してもOK。
|
26
|
-
$bufferSize = 76;
|
27
|
+
$bufferSize = 76+strlen(PHP_EOL);
|
27
28
|
while(!feof($file)){
|
28
29
|
$buffer = fread($file, $bufferSize);
|
29
30
|
echo base64_decode($buffer);
|