Local Database
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
Google Safe Browsing v5 از مشتری انتظار دارد که یک پایگاه داده محلی را حفظ کند، به جز زمانی که مشتری حالت بیدرنگ بدون ذخیرهسازی را انتخاب کند. فرمت و ذخیره سازی این پایگاه داده محلی به مشتری بستگی دارد. محتویات این پایگاه داده محلی را می توان از نظر مفهومی به عنوان یک پوشه حاوی لیست های مختلف به عنوان فایل در نظر گرفت و محتویات این فایل ها هش SHA256 یا پیشوندهای متناظر آنها با پیشوند هش چهار بایتی است که متداول ترین طول هش استفاده می شود.
لیست های موجود
فهرستها با نامهای متمایزشان که از یک قرارداد نامگذاری پیروی میکنند، شناسایی میشوند که در آن نام پسوندی وجود دارد که نشاندهنده طول هش است که باید در لیست انتظار داشته باشید. لیستهای هش با یک نوع تهدید اما طول هش متفاوت، فهرستی با نام جداگانه خواهند بود که دارای پسوندی است که طول هش را نشان میدهد.
لیست های زیر برای استفاده با روش های لیست هش در دسترس هستند.
نام لیست | مربوطه v4 ThreatType Enum | توضیحات |
---|
gc-32b | هیچ کدام | این لیست یک لیست کش جهانی است. این یک لیست ویژه است که فقط در حالت Real Time استفاده می شود. |
se-4b | SOCIAL_ENGINEERING | این لیست حاوی تهدیدهایی از نوع تهدید SOCIAL_ENGINEERING است. |
mw-4b | MALWARE | این لیست حاوی تهدیداتی از نوع تهدید بدافزار برای پلتفرم های دسکتاپ است. |
uws-4b | UNWANTED_SOFTWARE | این لیست حاوی تهدیداتی از نوع تهدید UNWANTED_SOFTWARE برای پلتفرم های دسکتاپ است. |
uwsa-4b | UNWANTED_SOFTWARE | این لیست حاوی تهدیداتی از نوع تهدید UNWANTED_SOFTWARE برای پلتفرم های اندروید است. |
pha-4b | POTENTIALLY_HARMFUL_APPLICATION | این لیست حاوی تهدیداتی از نوع تهدید POTENTIALLY_HARMFUL_APPLICATION برای پلتفرم های Android است. |
لیستهای اضافی میتوانند بعداً در دسترس قرار گیرند، در این زمان جدول بالا گسترش مییابد، و نتایج حاصل از روش hashList.list نتیجه مشابهی را با لیستهای بهروز نشان میدهد.
به روز رسانی پایگاه داده
کلاینت مرتباً متد hashList.get یا متد hashLists.batchGet را برای به روز رسانی پایگاه داده فراخوانی می کند. از آنجایی که مشتری معمولی می خواهد چندین لیست را در یک زمان به روز کند، توصیه می شود از روش hashLists.batchGet استفاده کنید.
نام لیست هرگز تغییر نام نخواهد داد. علاوه بر این، هنگامی که یک لیست ظاهر شد، هرگز حذف نخواهد شد (اگر لیست دیگر مفید نباشد، خالی می شود اما به وجود خود ادامه می دهد). بنابراین، مناسب است که این نام ها را در کد سرویس گیرنده Google Safe Browsing کدگذاری کنید.
هم روش hashList.get و هم روش hashLists.batchGet از به روز رسانی های افزایشی پشتیبانی می کنند. استفاده از به روز رسانی های افزایشی باعث صرفه جویی در پهنای باند و بهبود عملکرد می شود. به روز رسانی های افزایشی با ارائه یک دلتا بین نسخه مشتری از لیست و آخرین نسخه لیست کار می کنند. (اگر یک کلاینت به تازگی مستقر شده باشد و هیچ نسخه ای در دسترس نداشته باشد، یک به روز رسانی کامل در دسترس است.) به روز رسانی افزایشی شامل شاخص های حذف و اضافه شده است. ابتدا از مشتری انتظار می رود که ورودی های شاخص های مشخص شده را از پایگاه داده محلی خود حذف کند و سپس اضافات را اعمال کند.
در نهایت، برای جلوگیری از فساد، کلاینت باید داده های ذخیره شده را در مقابل چک جمع ارائه شده توسط سرور بررسی کند. هر زمان که جمع چک مطابقت نداشته باشد، مشتری باید به روز رسانی کامل را انجام دهد.
رمزگشایی محتوای فهرست
رمزگشایی هش ها و پیشوندهای هش
همه لیست ها با استفاده از یک رمزگذاری ویژه برای کاهش اندازه تحویل داده می شوند. این رمزگذاری با تشخیص اینکه لیستهای مرور ایمن Google از نظر مفهومی حاوی مجموعهای از پیشوندهای هش یا هش هستند، کار میکند که از نظر آماری از اعداد صحیح تصادفی قابل تشخیص نیستند. اگر بخواهیم این اعداد صحیح را مرتب کنیم و تفاوت مجاور آنها را بگیریم، انتظار می رود چنین تفاوت مجاور به یک معنا "کوچک" باشد. رمزگذاری Golomb-Rice سپس از این کوچکی سوء استفاده می کند.
فرض کنید که سه عبارت پسوند مسیر میزبان، یعنی a.example.com/
، b.example.com/
، و y.example.com/
، قرار است با استفاده از پیشوندهای هش 4 بایتی منتقل شوند. بعلاوه فرض کنید که پارامتر Rice که با k نشان داده شده است، انتخاب شده است
- سرور با محاسبه هش کامل برای این رشته ها شروع می کند که به ترتیب عبارتند از:
291bc5421f1cd54d99afcc55d166e2b9fe42447025895bf09dd41b2110a687dc a.example.com/
1d32c5084a360e58f1b87109637a6810acad97a861a7769e8f1841410d2a960c b.example.com/
f7a502e56e8b01c6dc242b35122683c9d25d07fb1f532d9853eb0ef3ff334f03 y.example.com/
سپس سرور پیشوندهای هش 4 بایتی را برای هر یک از موارد فوق تشکیل می دهد که 4 بایت اول هش کامل 32 بایتی است که به عنوان اعداد صحیح 32 بیتی بزرگ endian تفسیر می شود. endianness بزرگ به این واقعیت اشاره دارد که اولین بایت از هش کامل به مهم ترین بایت عدد صحیح 32 بیتی تبدیل می شود. این مرحله به اعداد صحیح 0x291bc542، 0x1d32c508 و 0xf7a502e5 منجر می شود.
لازم است سرور این سه پیشوند هش را به صورت واژگانی (معادل مرتب سازی عددی در big endian) مرتب کند و نتیجه مرتب سازی 0x1d32c508، 0x291bc542، 0xf7a502e5 است. اولین پیشوند هش بدون تغییر در فیلد first_value
ذخیره می شود.
سپس سرور دو تفاوت مجاور را محاسبه می کند که به ترتیب 0xbe9003a و 0xce893da3 هستند. با توجه به اینکه k به عنوان 30 انتخاب شده است، سرور این دو عدد را به قسمت های ضریب و قسمت های باقیمانده که به ترتیب 2 و 30 بیت هستند تقسیم می کند. برای عدد اول، قسمت ضریب صفر و باقیمانده 0xbe9003a است. برای عدد دوم، قسمت ضریب 3 است زیرا مهم ترین دو بیت 11 در باینری و بقیه 0xe893da3 است. برای یک ضریب مشخص q
به (1 << q) - 1
دقیقاً با استفاده از بیت های 1 + q
کدگذاری می شود. باقیمانده مستقیماً با استفاده از k بیت کدگذاری می شود. قسمت ضریب عدد اول به صورت 0 کدگذاری می شود و قسمت باقیمانده به صورت باینری 001011111010010000000000111010 است. قسمت ضریب عدد دوم به صورت 0111 کدگذاری می شود و قسمت باقیمانده 001110100010010011110110100011 است.
هنگامی که این اعداد به یک رشته بایت تبدیل می شوند، اندیان کمی استفاده می شود. از نظر مفهومی ممکن است تصور اینکه یک رشته بیت طولانی از بیتهای کماهمیت شروع میشود، آسانتر باشد: بخش ضریب عدد اول را میگیریم و قسمت باقیمانده عدد اول را پیشفرض میکنیم. سپس قسمت ضریب عدد دوم را پیشفرض میکنیم و قسمت باقیمانده را پیشفرض میکنیم. این باید به تعداد زیاد زیر منجر شود (خطوط و نظرات اضافه شده برای وضوح):
001110100010010011110110100011 # Second number, remainder part
0111 # Second number, quotient part
001011111010010000000000111010 # First number, remainder part
0 # First number, quotient part
نوشته شده در یک خط این خواهد بود
00111010001001001111011010001101110010111110100100000000001110100
بدیهی است که این تعداد بسیار بیشتر از 8 بیت موجود در یک بایت است. سپس رمزگذاری اندیان کوچک، 8 بیت کماهمیت را در آن عدد میگیرد و آن را به عنوان اولین بایت که 01110100 است، خروجی میدهد.
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
به طور کامل وجود ندارد)، در این صورت مشتری باید فوراً بهروزرسانی دیگری را انجام دهد.
جز در مواردی که غیر از این ذکر شده باشد،محتوای این صفحه تحت مجوز Creative Commons Attribution 4.0 License است. نمونه کدها نیز دارای مجوز Apache 2.0 License است. برای اطلاع از جزئیات، به خطمشیهای سایت Google Developers مراجعه کنید. جاوا علامت تجاری ثبتشده Oracle و/یا شرکتهای وابسته به آن است.
تاریخ آخرین بهروزرسانی 2025-07-24 بهوقت ساعت هماهنگ جهانی.
[null,null,["تاریخ آخرین بهروزرسانی 2025-07-24 بهوقت ساعت هماهنگ جهانی."],[],[],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."]]