MBとMiBは違う!ファイルサイズ単位の落とし穴
「ファイルサイズの上限は10MBです」という仕様書を見たとき、あなたはどう解釈しますか? 実は「MB」と「MiB」は明確に異なる単位であり、この混同が原因で境界値テストの失敗や本番障害が発生するケースがあります。この記事では、ファイルサイズ単位の正確な定義と、開発現場でよくある落とし穴を解説します。
MB と MiB の定義
ファイルサイズを表す単位には、SI単位系(10進数ベース)とIEC単位系(2進数ベース)の2種類があります。
| 単位 | 読み方 | バイト数 | 規格 |
|---|---|---|---|
| KB | キロバイト | 1,000 B | SI(10進数) |
| KiB | キビバイト | 1,024 B | IEC(2進数) |
| MB | メガバイト | 1,000,000 B | SI(10進数) |
| MiB | メビバイト | 1,048,576 B | IEC(2進数) |
| GB | ギガバイト | 1,000,000,000 B | SI(10進数) |
| GiB | ギビバイト | 1,073,741,824 B | IEC(2進数) |
1MBと1MiBの差は 48,576バイト(約4.86%) です。10MBと10MiBでは差が約485KBにもなります。この差が積み重なると、境界値テストで「10MB以下のファイルのはずが拒否された」という事態が起きます。
開発ツール・OS・クラウドでの扱いの違い
問題を複雑にするのは、各ツールやOSがこの単位を独自の解釈で使っていることです。
| ツール / 環境 | 「10MB」の解釈 | 実際のバイト数 |
|---|---|---|
| PHP(php.ini) | 10MiB | 10,485,760 B |
| Nginx(client_max_body_size) | 10MiB | 10,485,760 B |
| Windows エクスプローラー | MiB表示("MB"と表記) | 1,048,576 B / MB |
| macOS Finder | MB(10進数) | 1,000,000 B / MB |
| AWS S3 管理コンソール | MiB表示 | 1,048,576 B / MB |
| Gmail(添付上限) | MB(10進数) | 25,000,000 B |
特に注意が必要なのは、Windowsが「MB」と表示しながら実際には「MiB」の計算をしている点です。Windowsで「9.9 MB」と表示されたファイルは、実際には 9.9 × 1,048,576 = 10,381,301 バイト の場合があります。これは10MB(10,000,000バイト)より大きく、Gmail(25MB制限)でも問題にはなりませんが、PHP の upload_max_filesize = 10M(=10MiB = 10,485,760バイト)では通過できます。
PHP での実例
PHPの設定ファイルでは、単位は以下のように解釈されます。
; php.ini の設定
upload_max_filesize = 10M ; 10 MiB = 10,485,760 バイト
post_max_size = 12M ; 12 MiB = 12,582,912 バイト
アップロードされたファイルのサイズを検証する際は、バイト単位で比較するのが確実です。
// バイト単位で比較(安全)
$maxBytes = 10 * 1024 * 1024; // 10 MiB = 10,485,760 バイト
if ($_FILES['file']['size'] > $maxBytes) {
throw new \RuntimeException('ファイルサイズが上限を超えています');
}
// NG: 文字列の "10MB" を解析する場合は単位の解釈に注意
JavaScriptでの実例
// File API では size プロパティがバイト数を返す
const file = event.target.files[0];
const MAX_SIZE_MIB = 10 * 1024 * 1024; // 10 MiB
const MAX_SIZE_MB = 10 * 1000 * 1000; // 10 MB
// サーバー側に合わせて単位を統一する
if (file.size > MAX_SIZE_MIB) {
alert(`ファイルサイズ上限は 10 MiB (${MAX_SIZE_MIB.toLocaleString()} バイト) です`);
}
境界値テストへの影響
「10MBの上限」をテストする場合、サーバーの実際の上限値を把握してから適切なテストファイルを選ぶことが重要です。
- PHP
upload_max_filesize = 10M→ 上限は 10,485,760 バイト(10 MiB) - Gmail の添付上限 → 上限は 25,000,000 バイト(25 MB)
- Discord の無料プラン → 上限は 25,000,000 バイト(25 MB)
DevLab のしきい値テスト用ファイルはバイト単位で正確なサイズのファイルを提供しています。テスト前にサーバーの設定を確認し、対応するしきい値ファイルを選んでください。
まとめ
- MB = 1,000,000バイト(SI単位)、MiB = 1,048,576バイト(IEC単位)
- PHPやNginxは「M」を MiB として解釈する
- Windowsは「MB」と表示しながら MiB で計算する
- macOSは MB(10進数)で表示する
- テスト用ファイルはバイト単位で正確なものを使い、サーバー設定の解釈に合わせて選択する