إخفاء الهوية
استخدم واجهة إخفاء الهوية في قُبة لحماية البيانات الحساسة في النص بأساليب متعددة، منها الاستبدال والتقنيع والتجزئة والتشفير.
import {
Configuration,
SensitiveDataProtectionApi,
} from "@quba/sensitive-data-protection"
const text = `Patient John Smith (SSN: 123-45-6789) was admitted to
Dubai General Hospital on 2024-01-15. Contact: john.smith@email.com`
async function protectData(text: string) {
// Pass your API key on every request via the x-api-key header.
const api = new SensitiveDataProtectionApi(
new Configuration({ headers: { "x-api-key": "quba_..." } }),
)
return await api.anonymizeText({
text,
rules: [
{
type: "replace",
entities: [{ type: "model", value: "person" }],
replacement: "[PATIENT]",
},
{
type: "mask",
entities: [{ type: "regex", value: "\\d{3}-\\d{2}-\\d{4}" }],
masking_char: "*",
chars_to_mask: 7,
from_end: true,
},
{
type: "redact",
entities: [{ type: "model", value: "location" }],
},
{
type: "sha256",
entities: [{ type: "model", value: "email" }],
},
],
})
}
const response = await protectData(text)
console.log(response.text)
// Output: Patient [PATIENT] (SSN: ***-**-6789) was admitted to
// [REDACTED] on 2024-01-15. Contact: a1b2c3d4...from quba_sdp import Client, models
from quba_sdp.api import anonymize_text
text = """Patient John Smith (SSN: 123-45-6789) was admitted to
Dubai General Hospital on 2024-01-15. Contact: john.smith@email.com"""
# base_url defaults to the production API; pass your key via headers.
client = Client(headers={"x-api-key": "quba_..."})
response = anonymize_text.sync(
client=client,
body=models.AnonymizeRequestBody(
text=text,
rules=[
models.ReplaceRule(
entities=[models.ModelEntity(value="person")],
replacement="[PATIENT]",
),
models.MaskRule(
entities=[models.RegexEntity(value=r"\d{3}-\d{2}-\d{4}")],
masking_char="*",
chars_to_mask=7,
from_end=True,
),
models.RedactRule(entities=[models.ModelEntity(value="location")]),
models.SHA256Rule(entities=[models.ModelEntity(value="email")]),
],
),
)
print(response.text)
# Output: Patient [PATIENT] (SSN: ***-**-6789) was admitted to
# [REDACTED] on 2024-01-15. Contact: a1b2c3d4...استخدم model لتترك للذكاء الاصطناعي كشف أنواع الكيانات تلقائياً، واستخدم regex لاستهداف نمط محدد، مثل صيغة رقم تعريفي أو صيغة تاريخ.
// Model-based: AI finds the entity type
{ type: "model", value: "person" }
// Regex-based: matches your exact pattern
{ type: "regex", value: "\\d{3}-\\d{2}-\\d{4}" }# Model-based: AI finds the entity type
models.ModelEntity(value="person")
# Regex-based: matches your exact pattern
models.RegexEntity(value=r"\d{3}-\d{2}-\d{4}")القواعد
تحدّد القاعدة للواجهة أمرين: ما الذي تكشفه، وكيف تعالجه لإخفاء الهوية. ولكل قاعدة جزآن إلزاميان:
type: عملية إخفاء الهوية المطبَّقة (replaceأوredactأوmaskأوsha256أوsha512أوencrypt)entities: كيان مستهدف واحد أو أكثر، يُحدَّد كلٌّ منها بالنموذج أو بتعبير نمطي (regex)
{
type: "replace", // what to do
entities: [{ type: "model", value: "person" }], // what to find
replacement: "[PATIENT]" // anonymization option
}تمرّر القواعد في مصفوفة. تُقيَّم كل قاعدة على النص كاملاً بمعزل عن غيرها، لذا قد تطابق عدة قواعد مقاطع مختلفة وتعالجها، حتى لو تداخلت هذه المقاطع. وتُطبَّق القواعد بترتيب ورودها.
الكيانات المستهدفة
يُحدَّد كل كيان في entities إمّا بالنموذج أو بتعبير نمطي:
| النوع | الوصف | مثال |
|---|---|---|
model | يكشف الذكاء الاصطناعي نوع الكيان | { type: "model", value: "person" } |
regex | يُطابَق النص بالنمط الذي تحدده | { type: "regex", value: "\\d{3}-\\d{2}-\\d{4}" } |
ويمكن أن تجمع القاعدة الواحدة بين الطريقتين:
{
type: "redact",
entities: [
{ type: "model", value: "email" },
{ type: "regex", value: "[A-Z]{2}\\d{6}" }, // custom ID format
]
}models.RedactRule(
entities=[
models.ModelEntity(value="email"),
models.RegexEntity(value=r"[A-Z]{2}\d{6}"), # custom ID format
]
)حد الثقة
يرفق النموذج بكل كيان يكشفه درجة score (من 0.0 إلى 1.0) تعبّر عن ثقته في صحة الكشف. ويستبعد المعامل confidence_threshold الكيانات التي تقل درجة ثقتها عن الحد المطلوب.
await api.anonymizeText({
text: "...",
rules: [...],
confidence_threshold: 0.8, // only apply rules to high-confidence detections
})anonymize_text.sync(
client=client,
body=models.AnonymizeRequestBody(
text="...",
rules=[...],
confidence_threshold=0.8, # only apply rules to high-confidence detections
),
)- القيمة الافتراضية:
0.5 - تُطبَّق القواعد دائماً على مطابقات التعابير النمطية، فحد الثقة لا يؤثر فيها
- ارفع الحد (مثل
0.8) لتقليل الكشف الخاطئ، أو اخفضه لكشف عدد أكبر من الكيانات
عمليات إخفاء الهوية
الاستبدال
استبدل الكيانات المكتشَفة بنص تحدده:
{
type: "replace",
entities: [{ type: "model", value: "person" }],
replacement: "[REDACTED]" // default: "****"
}models.ReplaceRule(
entities=[models.ModelEntity(value="person")],
replacement="[REDACTED]", # default: "****"
)الحجب
أزِل الكيانات المكتشَفة من النص كلياً:
{
type: "redact",
entities: [{ type: "model", value: "email" }]
}models.RedactRule(entities=[models.ModelEntity(value="email")])التقنيع
غطِّ جزءاً من الكيان المكتشَف بحرف التقنيع:
{
type: "mask",
entities: [{ type: "model", value: "phone" }],
masking_char: "*", // default: "*"
chars_to_mask: 8, // null = mask all characters
from_end: true // false = mask from start
}
// +1-555-123-4567 → +1-555-***-****models.MaskRule(
entities=[models.ModelEntity(value="phone")],
masking_char="*", # default: "*"
chars_to_mask=8, # None = mask all characters
from_end=True, # False = mask from start
)
# +1-555-123-4567 → +1-555-***-****SHA256 / SHA512
حوّل الكيانات المكتشَفة إلى قيم مُجزّأة:
{
type: "sha256",
entities: [{ type: "model", value: "id" }]
}models.SHA256Rule(entities=[models.ModelEntity(value="id")])
# or models.SHA512Rule(...)التشفير
شفّر الكيانات المكتشَفة بمفتاح تحدده:
{
type: "encrypt",
entities: [{ type: "model", value: "person" }],
key: "your-encryption-key" // default: ""
}models.EncryptRule(
entities=[models.ModelEntity(value="person")],
key="your-encryption-key", # default: ""
)التعابير النمطية
يمكنك أيضاً استهداف أجزاء من النص بتعابير نمطية (regex):
{
type: "replace",
entities: [{ type: "regex", value: "\\d{4}-\\d{2}-\\d{2}" }],
replacement: "[DATE]"
}models.ReplaceRule(
entities=[models.RegexEntity(value=r"\d{4}-\d{2}-\d{2}")],
replacement="[DATE]",
)نتائج تطبيق القواعد
عند تنفيذ إخفاء الهوية، يُنشأ سجل نتيجة لكل كيان كُشف وعولج. وتُعاد هذه السجلات في response.results سجلَّ تدقيق مرتباً، بعنصر واحد لكل مقطع مطابق.
const response = await api.anonymizeText({ text, rules })
console.log(response.text) // the anonymized string
console.log(response.results) // one record per anonymization appliedresponse = anonymize_text.sync(
client=client,
body=models.AnonymizeRequestBody(text=text, rules=rules),
)
print(response.text) # the anonymized string
print(response.results) # one record per anonymization appliedتبيّن لك كل نتيجة:
- القاعدة المطبَّقة (
rule) - ما كُشف (
value: نوع الكيان أو التعبير النمطي) - موضعه في النص الأصلي (
input) - موضعه الجديد في النص الناتج (
output)
والنتيجة إمّا نتيجة نموذج (كيان كشفه الذكاء الاصطناعي) أو نتيجة تعبير نمطي (مقطع طابق نمطاً)، ويحدد الحقل type نوعها:
نتيجة النموذج
{
type: "model",
rule: "replace", // rule type that was applied
value: "PERSON", // entity type the model detected
score: 0.94, // AI confidence (0.0–1.0)
input: { start: 8, end: 18, value: "John Smith" }, // position in original text
output: { start: 8, end: 17, value: "[PATIENT]" }, // position in result text
}نتيجة التعبير النمطي
{
type: "regex",
rule: "mask", // rule type that was applied
value: "\\d{3}-\\d{2}-\\d{4}", // pattern that matched
input: { start: 20, end: 31, value: "123-45-6789" }, // position in original text
output: { start: 20, end: 31, value: "***-**-6789" }, // position in result text
}حقول TextRange
| الحقل | النوع | الوصف |
|---|---|---|
start | number | موضع بداية المقطع (مشمول) |
end | number | موضع نهاية المقطع (غير مشمول) |
value | string | المقطع الواقع في النطاق [start, end) |
تُرتَّب النتائج حسب موضعها في النص الناتج. استخدم مواضع input لتحديد كل مقطع في النص الأصلي، ومواضع output لإبراز المقاطع في النص الناتج.