Local Database
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
Google セーフ ブラウジング v5 では、クライアントがローカル データベースを維持することが想定されています(クライアントがストレージなしのリアルタイム モードを選択した場合を除きます)。このローカル データベースの形式と保存は、クライアントに任されています。このローカル データベースの内容は、さまざまなリストがファイルとして格納されているフォルダと概念的に考えることができます。これらのファイルの内容は SHA256 ハッシュ、またはそれに相当するプレフィックスです。最も一般的なハッシュ長は 4 バイトのハッシュ プレフィックスです。
使用可能なリスト
リストは、命名規則に従った一意の名前で識別されます。この名前には、リストに含まれるハッシュの長さを示す接尾辞が含まれています。脅威の種類は同じでハッシュの長さが異なるハッシュリストは、別の名前のリストとして、ハッシュの長さを示す接尾辞で修飾されます。
ハッシュリスト メソッドで使用できるリストは次のとおりです。
リスト名 |
対応する v4 ThreatType 列挙型 |
説明 |
gc-32b |
なし |
このリストはグローバル キャッシュ リストです。これは、リアルタイム モードの動作でのみ使用される特別なリストです。 |
se-4b |
SOCIAL_ENGINEERING |
このリストには、SOCIAL_ENGINEERING 脅威タイプの脅威が含まれています。 |
mw-4b |
MALWARE |
このリストには、デスクトップ プラットフォームのマルウェア脅威の種類の脅威が含まれています。 |
uws-4b |
UNWANTED_SOFTWARE |
このリストには、パソコン プラットフォームの UNWANTED_SOFTWARE 脅威タイプの脅威が含まれています。 |
uwsa-4b |
UNWANTED_SOFTWARE |
このリストには、Android プラットフォームの UNWANTED_SOFTWARE 脅威タイプの脅威が含まれています。 |
pha-4b |
POTENTIALLY_HARMFUL_APPLICATION |
このリストには、Android プラットフォームの POTENTIALLY_HARMFUL_APPLICATION 脅威タイプの脅威が含まれています。 |
今後、追加のリストが利用可能になり、上記の表が拡張される予定です。hashList.list メソッドの結果は、最新のリストと同様の結果になります。
データベースの更新
クライアントは、hashList.get メソッドまたは hashLists.batchGet メソッドを定期的に呼び出してデータベースを更新します。通常のクライアントは一度に複数のリストを更新する必要があるため、hashLists.batchGet メソッドを使用することをおすすめします。
リスト名は変更されません。また、一度表示されたリストは削除されません(リストが役に立たなくなった場合は空になりますが、存在し続けます)。したがって、これらの名前は Google セーフ ブラウジング クライアント コードにハードコードするのが適切です。
hashList.get メソッドと hashLists.batchGet メソッドの両方が、増分更新をサポートしています。増分更新を使用すると、帯域幅を節約し、パフォーマンスを向上させることができます。増分更新は、クライアントのリスト バージョンと最新バージョンのリストとの差分を配信することで機能します。(クライアントが新しくデプロイされ、利用可能なバージョンがない場合は、完全なアップデートが可能です)。増分更新には、削除インデックスと追加インデックスが含まれています。クライアントは、まず指定されたインデックスのエントリをローカル データベースから削除してから、追加を適用する必要があります。
最後に、破損を防ぐため、クライアントは保存されたデータをサーバーから提供されたチェックサムと照合する必要があります。チェックサムが一致しない場合、クライアントは完全な更新を実行する必要があります。
リスト コンテンツのデコード
ハッシュとハッシュ プレフィックスのデコード
すべてのリストは、サイズを小さくするために特別なエンコードを使用して配信されます。このエンコードは、Google Safe Browsing リストに、概念的には、ランダムな整数と統計的に区別できない一連のハッシュまたはハッシュ接頭辞が含まれていることを認識することで機能します。これらの整数を並べ替えて隣接する差を取ると、その差は「小さい」と見なされます。Golomb-Rice エンコードでは、この小ささを利用します。
4 バイトのハッシュ プレフィックスを使用して、3 つのホスト接尾辞パス プレフィックス式(a.example.com/
、b.example.com/
、y.example.com/
)を送信するとします。さらに、Rice パラメータ(k で表記)が次のように選択されているとします。
- サーバーは、まずこれらの文字列の完全なハッシュを計算します。これらの文字列はそれぞれ次のとおりです。
291bc5421f1cd54d99afcc55d166e2b9fe42447025895bf09dd41b2110a687dc a.example.com/
1d32c5084a360e58f1b87109637a6810acad97a861a7769e8f1841410d2a960c b.example.com/
f7a502e56e8b01c6dc242b35122683c9d25d07fb1f532d9853eb0ef3ff334f03 y.example.com/
サーバーは、上記の各項目に 4 バイトのハッシュ プレフィックスを形成します。これは、32 バイトの完全なハッシュの最初の 4 バイトであり、ビッグ エンディアン 32 ビット整数として解釈されます。ビッグエンディアンとは、完全なハッシュの最初のバイトが 32 ビット整数の最上位バイトになることを意味します。このステップの結果、整数 0x291bc542、0x1d32c508、0xf7a502e5 が生成されます。
サーバーは、これらの 3 つのハッシュ接頭辞を辞書順に並べ替える必要があります(ビッグ エンディアンでの数値並べ替えと同等)。並べ替えの結果は 0x1d32c508、0x291bc542、0xf7a502e5 です。最初のハッシュ接頭辞は、first_value
フィールドに変更なく保存されます。
サーバーは、2 つの隣接する差分(0xbe9003a と 0xce893da3)を計算します。k が 30 に選択されている場合、サーバーはこれらの 2 つの数値を、それぞれ 2 ビット長と 30 ビット長の商と剰余に分割します。最初の数値の場合、商は 0、余りは 0xbe9003a です。2 番目の数値の場合、商は 3 です。これは、上位 2 ビットがバイナリで 11 であり、余りが 0xe893da3 であるためです。特定の商 q
は、正確に 1 + q
ビットを使用して (1 << q) - 1
にエンコードされます。残りは k ビットを使用して直接エンコードされます。1 つ目の数値の商は 0 としてエンコードされ、余りはバイナリで 001011111010010000000000111010 です。2 つ目の数値の商は 0111 としてエンコードされ、余りは 001110100010010011110110100011 です。
これらの数値がバイト文字列に形成される場合、リトル エンディアンが使用されます。概念的には、最下位ビットから長いビット文字列が形成されていると想像するのが簡単です。最初の数値の商の部分を取り、最初の数値の剰余の部分を先頭に追加します。次に、2 番目の数値の商の部分を先頭に追加し、剰余の部分を先頭に追加します。すると、次の大きな数値が得られます(わかりやすくするために改行とコメントを追加しています)。
001110100010010011110110100011 # Second number, remainder part
0111 # Second number, quotient part
001011111010010000000000111010 # First number, remainder part
0 # First number, quotient part
1 行で記述すると次のようになります。
00111010001001001111011010001101110010111110100100000000001110100
この数は、1 バイトで使用できる 8 ビットをはるかに超えています。リトル エンディアン エンコードでは、その数値の最下位 8 ビットを取得し、最初のバイト(01110100)として出力します。わかりやすくするために、上記のビット文字列を最下位ビットから 8 個ずつグループ化できます。
0 01110100 01001001 11101101 00011011 10010111 11010010 00000000 01110100
リトルエンディアン エンコードでは、右から各バイトを取り出してバイト文字列に格納します。
01110100
00000000
11010010
10010111
00011011
11101101
01001001
01110100
00000000
概念的には、左側の大きな数値に新しい部分を先頭に追加(つまり、上位ビットを追加)しますが、右側(つまり下位ビット)からエンコードするため、エンコードとデコードを段階的に行うことができます。
最終的に、
additions_four_bytes {
first_value: 489866504
rice_parameter: 30
entries_count: 2
encoded_data: "t\000\322\227\033\355It\000"
}
クライアントは、上記の手順を逆に行うだけでハッシュ接頭辞をデコードできます。
削除インデックスのデコード
削除インデックスは、32 ビットの整数を使用して上記とまったく同じ手法でエンコードされます。
更新の頻度
クライアントは、フィールド minimum_wait_duration
でサーバーが返した値を調べ、その値を使用してデータベースの次の更新をスケジュールする必要があります。この値はゼロの場合があり(フィールド minimum_wait_duration
が完全に欠落している場合)、その場合はクライアントは直ちに別の更新を実行する必要があります。
特に記載のない限り、このページのコンテンツはクリエイティブ・コモンズの表示 4.0 ライセンスにより使用許諾されます。コードサンプルは Apache 2.0 ライセンスにより使用許諾されます。詳しくは、Google Developers サイトのポリシーをご覧ください。Java は Oracle および関連会社の登録商標です。
最終更新日 2025-07-25 UTC。
[null,null,["最終更新日 2025-07-25 UTC。"],[],[],null,["# Local Database\n\nGoogle Safe Browsing v5 expects the client to maintain a local database, except when the client chooses the [No-Storage Real-Time Mode](/safe-browsing/reference#no-storage-real-time-mode). It is up to the client the format and storage of this local database. The contents of this local database can conceptually be thought of as a folder containing various lists as files, and the contents of these files are SHA256 hashes, or their corresponding prefixes with four byte hash prefix being the most commonly used hash length.\n\n### Available Lists\n\nLists are identified by their distinct names which follows a naming convention where the name contains a suffix that signifies the length of the hash you should expect in the list. Hash lists with the same threat type but different hash length will be a separately named list that's qualified with a suffix that indicates the hash length.\n\nThe following lists are available for use with the hash list methods.\n\n| List Name | Corresponding v4 `ThreatType` Enum | Description |\n|-----------|------------------------------------|------------------------------------------------------------------------------------------------------|\n| `gc-32b` | None | This list is a Global Cache list. It is a special list only used in the Real-Time mode of operation. |\n| `se-4b` | `SOCIAL_ENGINEERING` | This list contains threats of the SOCIAL_ENGINEERING threat type. |\n| `mw-4b` | `MALWARE` | This list contains threats of the MALWARE threat type for desktop platforms. |\n| `uws-4b` | `UNWANTED_SOFTWARE` | This list contains threats of the UNWANTED_SOFTWARE threat type for desktop platforms. |\n| `uwsa-4b` | `UNWANTED_SOFTWARE` | This list contains threats of the UNWANTED_SOFTWARE threat type for Android platforms. |\n| `pha-4b` | `POTENTIALLY_HARMFUL_APPLICATION` | This list contains threats of the POTENTIALLY_HARMFUL_APPLICATION threat type for Android platforms. |\n\nAdditional lists can become available at a later date, at which time the above table will be expanded, and the results from the [hashList.list method](/safe-browsing/reference/rest/v5/hashList/list) will show a similar result with the most up to date lists.\n\n### Database Updates\n\nThe client will regularly call the [hashList.get method](/safe-browsing/reference/rest/v5/hashList/get) or the [hashLists.batchGet method](/safe-browsing/reference/rest/v5/hashLists/batchGet) to update the database. Since the typical client will want to update multiple lists at a time, it is recommended to use [hashLists.batchGet method](/safe-browsing/reference/rest/v5/hashLists/batchGet).\n\nThe list names will never be renamed. Furthermore, once a list has appeared, it will never be removed (if the list is no longer useful, it will become empty but will continue to exist). Therefore, it is appropriate to hard code these names in the Google Safe Browsing client code.\n\nBoth the [hashList.get method](/safe-browsing/reference/rest/v5/hashList/get) and the [hashLists.batchGet method](/safe-browsing/reference/rest/v5/hashLists/batchGet) support incremental updates. Using incremental updates saves bandwidth and improves performance. Incremental updates work by delivering a delta between client's version of the list and the latest version of the list. (If a client is newly deployed and does not have any versions available, a full update is available.) The incremental update contains removal indices and additions. The client is first expected to remove the entries at the specified indices from its local database, and then apply the additions.\n\nFinally, to prevent corruption, the client should check the stored data against the checksum provided by the server. Whenever the checksum does not match, the client should perform a full update.\n\n### Decoding the List Content\n\n#### Decoding Hashes and Hash Prefixes\n\nAll lists are delivered using a special encoding to reduce size. This encoding works by recognizing that Google Safe Browsing lists contain, conceptually, a set of hashes or hash prefixes, which are statistically indistinguishable from random integers. If we were to sort these integers and take their adjacent difference, such adjacent difference is expected to be \"small\" in a sense. [Golomb-Rice encoding](https://en.wikipedia.org/wiki/Golomb_coding) then exploits this smallness.\n\nSuppose that three host-suffix path-prefix expressions, namely `a.example.com/`, `b.example.com/`, and `y.example.com/`, are to be transmitted using 4-byte hash prefixes. Further suppose that the Rice parameter, denoted by k, is chosen to be\n\n1. The server would start by calculating the full hash for these strings, which are, respectively:\n\n 291bc5421f1cd54d99afcc55d166e2b9fe42447025895bf09dd41b2110a687dc a.example.com/\n 1d32c5084a360e58f1b87109637a6810acad97a861a7769e8f1841410d2a960c b.example.com/\n f7a502e56e8b01c6dc242b35122683c9d25d07fb1f532d9853eb0ef3ff334f03 y.example.com/\n\nThe server then forms 4-byte hash prefixes for each of the above, which is the first 4 bytes of the 32-byte full hash, interpreted as big-endian 32-bit integers. The big endianness refers to the fact that the first byte of the full hash becomes the most significant byte of the 32-bit integer. This step results in the integers 0x291bc542, 0x1d32c508, and 0xf7a502e5.\n\nIt is necessary for the server to sort these three hash prefixes lexicographically (equivalent to numerical sorting in big endian), and the result of the sorting is 0x1d32c508, 0x291bc542, 0xf7a502e5. The first hash prefix is stored unchanged in the `first_value` field.\n\nThe server then calculates the two adjacent differences, which are 0xbe9003a and 0xce893da3 respectively. Given that k is chosen to be 30, the server splits these two numbers into the quotient parts and remainder parts that are 2 and 30 bits long respectively. For the first number, the quotient part is zero and the remainder is 0xbe9003a; for the second number, the quotient part is 3 because the most significant two bits are 11 in binary and the remainder is 0xe893da3. For a given quotient `q` it is encoded into `(1 \u003c\u003c q) - 1` using exactly `1 + q` bits; the remainder is encoded directly using k bits. The quotient part of the first number is encoded as 0, and the remainder part is in binary 001011111010010000000000111010; the quotient part of the second number is encoded as 0111, and the remainder part is 001110100010010011110110100011.\n\nWhen these numbers are formed into a byte string, little endian is used. Conceptually it may be easier to imagine a long bitstring being formed starting from the least significant bits: we take the quotient part of the first number and prepend the remainder part of the first number; we then further prepend the quotient part of the second number and prepend the remainder part. This should result in the following large number (linebreaks and comments added for clarity): \n\n 001110100010010011110110100011 # Second number, remainder part\n 0111 # Second number, quotient part\n 001011111010010000000000111010 # First number, remainder part\n 0 # First number, quotient part\n\nWritten in a single line this would be \n\n 00111010001001001111011010001101110010111110100100000000001110100\n\nObviously this number far exceeds the 8 bits available in a single byte. The little endian encoding then takes the least significant 8 bits in that number, and outputs it as the first byte which is 01110100. For clarity, we can group the above bitstring into groups of eight starting from the least significant bits: \n\n 0 01110100 01001001 11101101 00011011 10010111 11010010 00000000 01110100\n\nThe little endian encoding then takes each byte from the right and puts that into a bytestring: \n\n 01110100\n 00000000\n 11010010\n 10010111\n 00011011\n 11101101\n 01001001\n 01110100\n 00000000\n\nIt can be seen that since we conceptually *prepend* new parts to the large number on the left (i.e. adding more significant bits) but we encode from the right (i.e. the least significant bits), the encoding and decoding can be performed incrementally.\n\nThis finally results in \n\n additions_four_bytes {\n first_value: 489866504\n rice_parameter: 30\n entries_count: 2\n encoded_data: \"t\\000\\322\\227\\033\\355It\\000\"\n }\n\nThe client simply follows the above steps in reverse to decode the hash prefixes.\n\n#### Decoding Removal Indices\n\nRemoval indices are encoded using the exact same technique as above using 32-bit integers.\n\n### Update Frequency\n\nThe client should inspect the server's returned value in the field `minimum_wait_duration` and use that to schedule the next update of the database. This value is possibly zero (the field `minimum_wait_duration` is completely missing), in which case the client SHOULD immediately perform another update."]]