דלג לתוכן

מחולל ומאמת CUIT/CUIL | כלי זיהוי מס ארגנטינאי

כלי המפיק מספר CUIT או CUIL ארגנטינאי תקין לבדיקה, או בודק אם מספר קיים עומד באלגוריתם ספרת הביקורת של רשות המסים AFIP. מיועד למפתחי מערכות שכר ומס.

מחולל CUIT/CUIL

הזן מספר DNI בן 8 ספרות או השתמש במחולל האקראי

CUIT/CUIL שנוצר
20-62990143-5

שימוש ב-DNI שנוצר אקראית

מחשבון טעינה...
📚

תיעוד

מחולל ומאמת CUIT/CUIL ארגנטינאי

מבוא

במערכות המס והעבודה של ארגנטינה, תיתקל באופן קבוע בשני מזהים קריטיים: CUIT (Clave Única de Identificación Tributaria) ו-CUIL (Clave Única de Identificación Laboral). חשוב לחשוב על CUIT כמספר זיהוי מס לעסקים ויחידים המשלמים מסים, בעוד CUIL מזהה עובדים במערכת הביטחון הסוציאלי. שניהם משתמשים באותו פורמט של 11 ספרות ובאלגוריתם אימות, מה שהופך את בדיקת יישומים המטפלים במספרים אלה למיוחדת במינה.

בעת פיתוח תוכנה לשוק הארגנטיני, אתה זקוק לנתוני בדיקה תקפים. לשם כך משמש כלי זה. תוכל ליצור מספרי CUIT/CUIL מתמטית תקפים לבדיקות מבלי להשתמש במידע אישי אמיתי, או לאמת מספרים קיימים כדי להבטיח שהם תואמים את האלגוריתם הרשמי של AFIP. מה שמיוחד במיוחד הוא שהכלי מטפל הן בצד היצירה (יצירת מספרים תקפים לפי דרישה) והן בצד האימות (תפיסת שגיאות בפורמט, קודי סוג לא תקפים וספרות אימות שגויות לפני שהם גורמים לבעיות בייצור).

מבנה וחישוב CUIT/CUIL

הבנת הפורמט

מספר CUIT/CUIL תקף מורכב מ-11 ספרות המוצגות בדרך כלל בפורמט XX-XXXXXXXX-X. הנה איך זה מתפרק:

  1. קוד סוג (2 הספרות הראשונות): מזהה את סוג הישות

    • 20, 23, 24: גברים (CUIL)
    • 27: נשים (CUIL)
    • 30, 33, 34: חברות וארגונים (CUIT)
  2. מספר ת"ז (8 הספרות האמצעיות): עבור יחידים, זהו מספר תעודת הזהות הלאומית (DNI). מלכודת נפוצה: אם ת"ז בפועל קצרה מ-8 ספרות, יש למלא עם אפסים מובילים. לדוגמה, ת"ז 1234567 הופכת ל-01234567 ב-CUIT/CUIL. חברות מקבלות מספר ייחודי מוקצה במקום זאת.

  3. ספרת אימות (הספרה האחרונה): ספרת בדיקה זו מאמתת את המספר כולו באמצעות אלגוריתם משוקלל. אם ספרה זו אינה תואמת את החישוב, כל ה-CUIT/CUIL הוא לא תקף - דבר שלעתים קרובות מפתיע מפתחים בעת בניית נתוני בדיקה ידניים.

חישוב ספרת האימות

ספרת האימות משתמשת באלגוריתם משוקלל מודולו-11. הנה איך זה עובד:

  1. קח את 10 הספרות הראשונות של CUIT/CUIL (קוד סוג + ת"ז)
  2. הכפל כל ספרה במשקל המתאים: 5, 4, 3, 2, 7, 6, 5, 4, 3, 2
  3. חבר את כל המכפלות
  4. חשב: 11 פחות (סכום מודולו 11)
  5. טפל במקרי קצה: אם התוצאה היא 11, השתמש ב-0; אם היא 10, השתמש ב-9

מה שמבלבל אנשים ביותר הם מקרי הקצה בשלבים 5. בעת בדיקה, תקבל לעתים תוצאה של 10 או 11, ושכחת למפות אותם ל-9 ו-0 בהתאמה גורמת לכשלי אימות שקשה לנתח אם אינך מודע לכלל זה.

מבחינה מתמטית, זה ניתן לביטוי כך:

VD=11((i=110di×wi)mod11)VD = 11 - ((\sum_{i=1}^{10} d_i \times w_i) \bmod 11)

כאשר:

  • VDVD הוא ספרת האימות
  • did_i היא הספרה ה-ii מתוך 10 הספרות הראשונות
  • wiw_i הוא המשקל המתאים מהסדרה [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
  • מקרים מיוחדים: אם VD=11VD = 11 אזי VD=0VD = 0, אם VD=10VD = 10 אזי VD=9VD = 9

מדריך שלב אחר שלב

שימוש בגנרטור

  1. בחר את הכרטיסייה "גנרטור" בראש ממשק הכלי.

  2. בחר קוד סוג מתפריט הנפתח:

    • 20: זכר (CUIL)
    • 23: עסק (CUIT)
    • 24: עסק זמני (CUIT)
    • 27: נקבה (CUIL)
    • 30: תאגיד (CUIT)
    • 33: עמותה (CUIT)
    • 34: קרן (CUIT)
  3. הזן מספר ת"ז (אופציונלי):

    • הכנס מספר ת"ז בן 8 ספרות בשדה המתאים
    • אם נשאר ריק, הכלי יוליד ת"ז אקראית
    • אם תזין פחות מ-8 ספרות, המערכת תוסיף אפסים מלפנים
  4. הולדת ת"ז אקראית (אופציונלי):

    • לחץ על כפתור "אקראי" כדי להוליד מספר ת"ז אקראי בן 8 ספרות
  5. הצג CUIT/CUIL שנוצר:

    • הכלי מציג אוטומטית CUIT/CUIL תקף על בסיס הקלטים שלך
    • התבנית תהיה XX-XXXXXXXX-X עם ספרת אימות נכונה
  6. העתק את התוצאה:

    • לחץ על סמל ההעתקה כדי להעתיק את CUIT/CUIL שנוצר ללוח
    • הודעת אישור תופיע בהעתקה מוצלחת

שימוש במאמת

  1. בחר את הכרטיסייה "מאמת" בראש ממשק הכלי.

  2. הזן CUIT/CUIL לאימות:

    • הכנס CUIT/CUIL בתבנית XX-XXXXXXXX-X
    • הכלי יעצב אוטומטית את הקלט עם מקפים בזמן ההקלדה
    • ניתן גם להזין את המספר ללא מקפים (XXXXXXXXXXX)
  3. לחץ על כפתור "אמת":

    • הכלי יבדוק את התבנית, קוד הסוג וספרת האימות
  4. הצג תוצאת אימות:

    • עבור מספרי CUIT/CUIL תקפים, תופיע הודעת הצלחה ירוקה
    • עבור מספרים לא תקפים, תופיע הודעת שגיאה אדומה שתסביר את הבעיה:
      • תבנית לא תקינה (חייבת להיות XX-XXXXXXXX-X)
      • קוד סוג לא תקין (חייב להיות אחד מ: 20, 23, 24, 27, 30, 33, 34)
      • ספרת אימות לא תקינה
  5. מידע נוסף:

    • עבור מספרים תקפים, הכלי מציג פירוק של הרכיבים:
      • קוד סוג ומשמעותו
      • מספר ת"ז
      • ספרת אימות

טעויות נפוצות ושיטות עבודה מיטביות

בעבודה עם אימות CUIT/CUIL ביישומים שלכם, שימו לב למכשולים השכיחים הבאים:

בעיות אפס-מילוי: התקלה הנפוצה ביותר שנתקלתי בה כוללת מספרי DNI עם אפסים מובילים. כאשר מישהו מזין DNI "1234567", הקוד שלכם צריך לטפל בו כ-"01234567" לבניית CUIT/CUIL. רבים מהיישומים ממירים למספרים שלמים לעיבוד, מה שמסיר אפסים מובילים. השתמשו בפעולות מחרוזת עם מילוי נכון במקום זאת.

בלבול קוד סוג: לא כל מספרי שתיים-ספרתיים הם קודי סוג תקפים. רק 20, 23, 24, 27, 30, 33, 34 עובדים. ראיתי מערכות המקבלות כל קידומת שתיים-ספרתית, מה שמוביל למספרים "נראים תקפים" כמו 21-12345678-X שנכשלים באימות AFIP. תמיד אמתו את קוד הסוג לפני חישוב ספרת הבדיקה.

הנחות מגדר: קוד סוג 20 (זכר) ו-27 (נקבה) אינם ניתנים להחלפה. אם אתם יוצרים CUIL באופן אוטומטי על בסיס נתונים דמוגרפיים, ודאו שקוד הסוג תואם את המגדר הרשום ב-RENAPER (הרישום הלאומי של ארגנטינה). אי-התאמות גורמות לדחייה כאשר אנשים מנסים להשתמש במספרים אלה בשירותים ממשלתיים.

טיפול במקפים: חלק מהיישומים דורשים מקפים בעוד אחרים דוחים אותם. שיטת העבודה המיטבית: קבלו שני הפורמטים בשדות קלט (עם או בלי מקפים), הסירו מקפים לפני אימות, אחסנו את הגרסה ללא מקפים במסדי נתונים, והוסיפו מקפים רק למטרות תצוגה.

אימות חסר: אלגוריתם האימות מזהה שגיאות פורמט אך אינו מאשר שה-CUIT/CUIL רשום. בסביבת ייצור, אמתו תחילה פורמט (מהר), ואז וודאו מול מסד הנתונים של AFIP (איטי יותר אך סמכותי). גישה דו-שלבית זו מזהה שגיאות הקלדה מיידית תוך הבטחת תקפות המספר.

בדיקת מקרי קצה: תמיד בדקו עם ספרות בדיקה של 0 ו-9 - אלה נובעות ממקרים מיוחדים באלגוריתם. בדקו גם DNI המתחילים באפס כדי להבטיח שהיגיון המילוי שלכם עובד כראוי.

מקרי שימוש ויישומים מעשיים

פיתוח ובדיקות

פיתוח תוכנה: בעת בניית יישומים לשוק הארגנטיני, תזדקק לנתוני בדיקה שעוברים אימות מבלי להשתמש במידע אמיתי של משתמשים. הנה היכן זה הופך קריטי:

  • פלטפורמות מסחר אלקטרוני: מעבדי תשלומים ומערכות חשבוניות דורשים מספרי CUIT/CUIL תקפים. במהלך בדיקות עומס, עשויים להידרש אלפי מספרים תקפים כדי לדמות הרשמות משתמשים ריאליסטיות.
  • תוכנת הנהלת חשבונות: מודולי דיווח מס מאמתים את פורמט CUIT/CUIL לפני הגשה ל-AFIP. בדיקת כללי אימות אלה דורשת מספרים שעוברים את אלגוריתם ספרת הביקורת.
  • מערכות ניהול משאבי אנוש: עיבוד תשלומים וביטוח לאומי תלויים במספרי CUIL תקפים. תרחיש נפוץ: בודקים זרימות קליטת עובדים ומוודאים שמספרי CUIL לא תקפים מפעילים הודעות שגיאה מתאימות.
  • יישומי בנקאות: תהליכי KYC (הכר את הלקוח) מאמתים CUIT/CUIL כחלק מפתיחת חשבון. בניסיוני, מקרי קצה כמו אי התאמות בקוד סוג לעתים קרובות מתגלים במהלך בדיקות אינטגרציה.

אכלוס מסד נתונים: בעת זריעת מסדי נתוני בדיקה, שימוש במספרי CUIT/CUIL תקפים אלגוריתמית מבטיח שאילוצי מסד הנתונים והטריגרים שלך פועלים כצפוי. זה חשוב במיוחד בעת בדיקת סקריפטי העברת נתונים או תהליכי ETL המאמתים מספרי זיהוי.

בדיקת אימות טופס: בדוק הן את הנתיב השמח והן תנאי שגיאה. צור מספרים תקפים כדי לאשר הגשה מוצלחת, ואז שנה את ספרת האימות כדי להבטיח שאימות הממשק הקדמי והאחורי שלך תופס את השגיאה לפני שהיא מגיעה למסד הנתונים.

בדיקת API: בדיקות אינטגרציה צריכות להשתמש במספרי CUIT/CUIL תקפים בעומסי הבקשות. זה מונע שליליים שגויים שבהם בדיקות נכשלות בשל נתוני בדיקה לא תקפים במקום באגים ממשיים בהיגיון ה-API.

אוטומציית QA: בדיקות פרמטריות מרוויחות מיצירת CUIT/CUIL דינמית. במקום לקבע ערכי בדיקה שעלולים לסתור בין הרצות בדיקה, צור מספרים תקפים טריים לכל ביצוע בדיקה.

מטרות חינוכיות

למידת אלגוריתמי אימות: אלגוריתם האימות של CUIT/CUIL מדגים יישום מעשי של אריתמטיקת מודולו וספרות ביקורת ממושקלות. דפוס זהה מופיע במערכות זיהוי אחרות ברחבי העולם—מספרי כרטיסי אשראי (אלגוריתם לוהן), קודי ISBN, ומספרי מע"מ אירופיים כולם משתמשים בגישות סכום ביקורת ממושקלות דומות. הבנת אופן פעולת אימות CUIT/CUIL מספקת תובנה מדוע אלגוריתמים אלה קיימים: הם תופסים שגיאות העתקה כמו ספרות מוחלפות או טעויות ספרה בודדת.

הוראת אימות נתונים: בעת הכשרת מפתחים צעירים באימות קלט, מערכת CUIT/CUIL מציעה דוגמה מעשית המורכבת יותר מאימות דוא"ל אך פשוטה יותר מאימות קריפטוגרפי. היא מדגימה את עקרון ההגנה בעומק: אימות פורמט (11 ספרות), אימות כללי עסקיים (קודי סוג תקפים), ואימות אלגוריתמי (ספרת ביקורת).

פיתוח עסקים בינלאומי: אם אתה בונה מערכות לשווקים לטינו-אמריקניים, הבנת CUIT/CUIL עוזרת לך לתפוס מערכות דומות במדינות שכנות. לברזיל יש CPF/CNPJ, לצ'ילה יש RUT, ולאורוגוואי יש RUT—כולם משתמשים באלגוריתמי ספרת ביקורת. התבניות שאתה לומד כאן מועברות למערכות אלה.

חלופות ושיקולי הפקה

בעוד כלי זה עובד היטב לפיתוח ובדיקות, לסביבות הפקה יש דרישות שונות:

אימות ממשלתי רשמי: ביישומים חיים, אימות אלגוריתמי לבד אינו מספיק—עליך לאמת שה-CUIT/CUIL רשום בפועל עם AFIP (Administración Federal de Ingresos Públicos). AFIP מספקת שירותי אינטרנט לאימות בזמן אמת, אף כי תצטרך להירשם ולאמת זהות כדי לגשת אליהם. הקטע: מספר יכול להיות תקף מבחינה מתמטית אך לא מוקצה רשמית, לכן תמיד יישם שני שכבות אימות בהפקה.

ספריות וחבילות: אם אתה משלב אימות CUIT/CUIL בבסיס הקוד שלך, שקול ספריות מבוססות אלה במקום לכתוב משלך:

  • JavaScript: validar-cuit ב-npm מטפל באימות ועיצוב
  • PHP: ספריית afip-php מספקת אימות ואינטגרציית שירות אינטרנט של AFIP
  • Python: py-cuit ב-PyPI מיישם את האלגוריתם המלא

שימוש בספריות מתוחזקות מפחית את הסיכון לבאגי יישום ולעתים קרובות כולל מקרי קצה שעלולים להחמיץ בקוד מותאם אישית.

חישוב ידני: למטרות למידה או ניפוי באגים, עבודה דרך האלגוריתם ידנית מסייעת בהבנה מוצקה. קח מחשבון ודוגמת CUIT/CUIL, ואז עקוב אחר תהליך ההכפלה הממושקל שלב אחר שלב.

שירותי אימות ארגוניים: יישומים בקנה מידה גדול עשויים להרוויח משירותי אימות צד שלישי שלא רק בודקים פורמט אלא גם מצולבים מול מסדי נתונים מסחריים. שירותים אלה יכולים לסמן עסקים לא פעילים, לזהות ישויות מוטלות סנקציה, או לספק מטא-נתונים נוספים על בעל ה-CUIT/CUIL.

היסטוריה של מערכת CUIT/CUIL

מערכת הזיהוי CUIT/CUIL בארגנטינה התפתחה באופן משמעותי מאז הקמתה:

מקורות ויישום

ה-CUIT (Clave Única de Identificación Tributaria) הוצג לראשונה בארגנטינה בשנות ה-70 כחלק מהמאמצים לשדרג את מערכת גביית המסים. הרשות הפדרלית להכנסות ציבוריות (AFIP) יישמה מזהה ייחודי זה כדי לעקוב אחר משלמי מסים ביעילות יותר ולצמצם הון שחור.

ה-CUIL (Clave Única de Identificación Laboral) הוצג מאוחר יותר במיוחד כדי לזהות עובדים במערכת הביטחון הסוציאלי, תוך יצירת הבחנה בין זיהוי מס לזיהוי עבודה תוך שמירה על פורמט עקבי.

התפתחות ודיגיטציה

בשנות ה-90, עם רפורמות כלכליות משמעותיות בארגנטינה, מערכת CUIT/CUIL הפכה חשובה יותר במעקב אחר פעילות כלכלית. המערכת דוגמה עוד יותר, ומערכות אימות מקוונות יושמו.

תחילת שנות ה-2000 הביאה עימה שילוב של מערכת CUIT/CUIL עם שירותי ממשל דיגיטליים שונים, והפכה אותה לרכיב חיוני ביוזמות הממשל האלקטרוני של ארגנטינה. תקופה זו גם ראתה את תקנון אלגוריתם האימות והפורמט המשמשים עד היום.

התפתחויות אחרונות

בשנים האחרונות, AFIP שיפרה את תהליכי האבטחה והאימות עבור מספרי CUIT/CUIL, תוך יישום מערכות אימות מתוחכמות יותר ושילובן עם מאגרי מידע ממשלתיים אחרים. המערכת משחקת כעת תפקיד מכריע במאמצי ארגנטינה למאבק בהון שחור ולהבניית הכלכלה.

כיום, CUIT/CUIL משמש לא רק למטרות מס ותעסוקה, אלא גם למגוון רחב של פעילויות כולל בנקאות, עסקאות נדל"ן, שירותי תשתית וקניות מקוונות, והפך למזהה חיוני עבור יחידים ועסקים הפועלים בארגנטינה.

שיקולי יישום

בעת יישום אימות CUIT/CUIL במערכות שלכם, שקלו את ההיבטים הטכניים הבאים:

יציבות האלגוריתם: אלגוריתם האימות הנוכחי של CUIT/CUIL נותר ללא שינוי מאז התקנונו בשנות ה-90. על פי התיעוד הטכני של AFIP, גישת ספרת הביקורת של מודולו-11 המשוקללת מקודדת בהחלטה כללית 2854/2010 ותקנות עוקבות. יציבות זו אומרת שיישומים נדירות פעמים זקוקים לעדכונים, אך עליכם לעקוב אחר הודעות AFIP לגבי שינויים רגולטוריים כלשהם.

אופטימיזציית ביצועים: אלגוריתם האימות הוא זול מבחינה חישובית - רק 10 כפלים, חיבור אחד ופעולת מודולו אחת. עבור מערכות בעלות תפוקה גבוהה המעבדות אלפי אימותים בשנייה, צוואר הבקבוק הוא בדרך כלל עיכוב רשת בעת אימות מול מסד הנתונים של AFIP, ולא האלגוריתם עצמו. שקלו לשמור בזיכרון מטמון את תוצאות האימות של AFIP עם TTLs מתאימים (בדרך כלל 24 שעות) כדי לאזן בין טריות לביצועים.

קידוד תווים: בעת עיבוד נתוני CUIT/CUIL ממקורות חיצוניים (PDFs, מסמכים סרוקים, גרירת אינטרנט), שימו לב לבעיות קידוד תווים. המקף עשוי להופיע כמו מקף ארוך (U+2014), מקף בינוני (U+2013), או סימן מינוס (U+2212) במקום המקף הסטנדרטי (U+002D). נרמלו אותם לפני האימות כדי למנוע שלילות שגויות.

בינלאומיות: אם היישום שלכם משרת שווקים לטינו-אמריקניים מרובים, שימו לב שה-CUIT/CUIL של ארגנטינה משתמש במודולו-11 עם משקלות ספציפיות, בעוד שה-RUT של צ'ילה משתמש במודולו-11 עם משקלות שונות, וה-CPF/CNPJ של ברזיל משתמש במודולו-11 עם דפוס שונה. אל תניחו שהאלגוריתמים זהים - לכל מערכת של מדינה יש כללים שונים. להבנה רחבה יותר של אלגוריתמי ספרת ביקורת, ראו את תקן ISO/IEC 7064 אשר מפרט סכמות אימות מודולו שונות.

אחסון מסד נתונים: אחסנו מספרי CUIT/CUIL ללא מקפים כ-CHAR(11) בגודל קבוע או כ-BIGINT אם מסד הנתונים שלכם תומך במספרים בני 11 ספרות ללא אובדן דיוק. הוסיפו מגבלת בדיקה המאמתת את ספרת הביקורת ברמת מסד הנתונים כרשת ביטחון נגד נתונים מקולקלים. צרו אינדקסים בשדה זה לחיפושים יעילים כאשר משתמשים מחפשים לפי CUIT/CUIL.

דוגמאות קוד

Python

1def calculate_verification_digit(type_code, dni):
2    # המר למחרוזת והבטח שה-DNI הוא 8 ספרות עם אפסים מובילים
3    type_code_str = str(type_code)
4    dni_str = str(dni).zfill(8)
5    
6    # שלב את קוד הסוג ו-DNI
7    digits = type_code_str + dni_str
8    
9    # משקלות לכל מיקום
10    weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
11    
12    # חשב סכום מכפלות
13    sum_products = sum(int(digits[i]) * weights[i] for i in range(10))
14    
15    # חשב ספרת אימות
16    verification_digit = 11 - (sum_products % 11)
17    
18    # מקרים מיוחדים
19    if verification_digit == 11:
20        verification_digit = 0
21    elif verification_digit == 10:
22        verification_digit = 9
23    
24    return verification_digit
25
26def generate_cuit_cuil(type_code, dni=None):
27    import random
28    
29    # קודי סוג תקפים
30    valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
31    
32    if type_code not in valid_type_codes:
33        raise ValueError(f"קוד סוג לא תקף. חייב להיות אחד מ: {valid_type_codes}")
34    
35    # צור DNI אקראי אם לא סופק
36    if dni is None:
37        dni = random.randint(10000000, 99999999)
38    
39    # חשב ספרת אימות
40    verification_digit = calculate_verification_digit(type_code, dni)
41    
42    # עצב CUIT/CUIL
43    return f"{type_code}-{str(dni).zfill(8)}-{verification_digit}"
44
45def validate_cuit_cuil(cuit_cuil):
46    # הסר מקפים אם קיימים
47    cuit_cuil_clean = cuit_cuil.replace("-", "")
48    
49    # בדוק פורמט בסיסי
50    if not cuit_cuil_clean.isdigit() or len(cuit_cuil_clean) != 11:
51        return False, "פורמט לא תקף"
52    
53    # חלץ חלקים
54    type_code = int(cuit_cuil_clean[0:2])
55    dni = int(cuit_cuil_clean[2:10])
56    verification_digit = int(cuit_cuil_clean[10])
57    
58    # אמת קוד סוג
59    valid_type_codes = [20, 23, 24, 27, 30, 33, 34]
60    if type_code not in valid_type_codes:
61        return False, "קוד סוג לא תקף"
62    
63    # חשב והשווה ספרת אימות
64    calculated_digit = calculate_verification_digit(type_code, dni)
65    if calculated_digit != verification_digit:
66        return False, "ספרת אימות לא תקפה"
67    
68    return True, "CUIT/CUIL תקף"
69
70# שימוש לדוגמה
71print(generate_cuit_cuil(20, 12345678))  # צור עבור DNI ספציפי
72print(generate_cuit_cuil(27))  # צור עם DNI אקראי
73print(validate_cuit_cuil("20-12345678-9"))  # אמת CUIT/CUIL
74

JavaScript

1function calculateVerificationDigit(typeCode, dni) {
2  // המר למחרוזת והבטח שה-DNI הוא 8 ספרות עם אפסים מובילים
3  const typeCodeStr = typeCode.toString();
4  const dniStr = dni.toString().padStart(8, '0');
5  
6  // שלב את קוד הסוג ו-DNI
7  const digits = typeCodeStr + dniStr;
8  
9  // משקלות לכל מיקום
10  const weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
11  
12  // חשב סכום מכפלות
13  let sumProducts = 0;
14  for (let i = 0; i < 10; i++) {
15    sumProducts += parseInt(digits[i]) * weights[i];
16  }
17  
18  // חשב ספרת אימות
19  let verificationDigit = 11 - (sumProducts % 11);
20  
21  // מקרים מיוחדים
22  if (verificationDigit === 11) {
23    verificationDigit = 0;
24  } else if (verificationDigit === 10) {
25    verificationDigit = 9;
26  }
27  
28  return verificationDigit;
29}
30
31function generateCuitCuil(typeCode, dni) {
32  // קודי סוג תקפים
33  const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
34  
35  if (!validTypeCodes.includes(typeCode)) {
36    throw new Error(`קוד סוג לא תקף. חייב להיות אחד מ: ${validTypeCodes.join(', ')}`);
37  }
38  
39  // צור DNI אקראי אם לא סופק
40  if (dni === undefined) {
41    dni = Math.floor(Math.random() * 90000000) + 10000000;
42  }
43  
44  // חשב ספרת אימות
45  const verificationDigit = calculateVerificationDigit(typeCode, dni);
46  
47  // עצב CUIT/CUIL
48  return `${typeCode}-${dni.toString().padStart(8, '0')}-${verificationDigit}`;
49}
50
51function validateCuitCuil(cuitCuil) {
52  // הסר מקפים אם קיימים
53  const cuitCuilClean = cuitCuil.replace(/-/g, '');
54  
55  // בדוק פורמט בסיסי
56  if (!/^\d{11}$/.test(cuitCuilClean)) {
57    return { isValid: false, errorMessage: 'פורמט לא תקף' };
58  }
59  
60  // חלץ חלקים
61  const typeCode = parseInt(cuitCuilClean.substring(0, 2));
62  const dni = parseInt(cuitCuilClean.substring(2, 10));
63  const verificationDigit = parseInt(cuitCuilClean.substring(10, 11));
64  
65  // אמת קוד סוג
66  const validTypeCodes = [20, 23, 24, 27, 30, 33, 34];
67  if (!validTypeCodes.includes(typeCode)) {
68    return { isValid: false, errorMessage: 'קוד סוג לא תקף' };
69  }
70  
71  // חשב והשווה ספרת אימות
72  const calculatedDigit = calculateVerificationDigit(typeCode, dni);
73  if (calculatedDigit !== verificationDigit) {
74    return { isValid: false, errorMessage: 'ספרת אימות לא תקפה' };
75  }
76  
77  return { isValid: true };
78}
79
80// שימוש לדוגמה
81console.log(generateCuitCuil(20, 12345678)); // צור עבור DNI ספציפי
82console.log(generateCuitCuil(27)); // צור עם DNI אקראי
83console.log(validateCuitCuil("20-12345678-9")); // אמת CUIT/CUIL
84

Java

1import java.util.Arrays;
2import java.util.List;
3import java.util.Random;
4
5public class CuitCuilUtils {
6    private static final List<Integer> VALID_TYPE_CODES = Arrays.asList(20, 23, 24, 27, 30, 33, 34);
7    private static final int[] WEIGHTS = {5, 4, 3, 2, 7, 6, 5, 4, 3, 2};
8    
9    public static int calculateVerificationDigit(int typeCode, int dni) {
10        // המר למחרוזת והבטח שה-DNI הוא 8 ספרות עם אפסים מובילים
11        String typeCodeStr = String.valueOf(typeCode);
12        String dniStr = String.format("%08d", dni);
13        
14        // שלב את קוד הסוג ו-DNI
15        String digits = typeCodeStr + dniStr;
16        
17        // חשב סכום מכפלות
18        int sumProducts = 0;
19        for (int i = 0; i < 10; i++) {
20            sumProducts += Character.getNumericValue(digits.charAt(i)) * WEIGHTS[i];
21        }
22        
23        // חשב ספרת אימות
24        int verificationDigit = 11 - (sumProducts % 11);
25        
26        // מקרים מיוחדים
27        if (verificationDigit == 11) {
28            verificationDigit = 0;
29        } else if (verificationDigit == 10) {
30            verificationDigit = 9;
31        }
32        
33        return verificationDigit;
34    }
35    
36    public static String generateCuitCuil(int typeCode, Integer dni) {
37        if (!VALID_TYPE_CODES.contains(typeCode)) {
38            throw new IllegalArgumentException("קוד סוג לא תקף. חייב להיות אחד מ: " + VALID_TYPE_CODES);
39        }
40        
41        // צור DNI אקראי אם לא סופק
42        if (dni == null) {
43            Random random = new Random();
44            dni = 10000000 + random.nextInt(90000000);
45        }
46        
47        // חשב ספרת אימות
48        int verificationDigit = calculateVerificationDigit(typeCode, dni);
49        
50        // עצב CUIT/CUIL
51        return String.format("%d-%08d-%d", typeCode, dni, verificationDigit);
52    }
53    
54    public static ValidationResult validateCuitCuil(String cuitCuil) {
55        // הסר מקפים אם קיימים
56        String cuitCuilClean = cuitCuil.replace("-", "");
57        
58        // בדוק פורמט בסיסי
59        if (!cuitCuilClean.matches("\\d{11}")) {
60            return new ValidationResult(false, "פורמט לא תקף");
61        }
62        
63        // חלץ חלקים
64        int typeCode = Integer.parseInt(cuitCuilClean.substring(0, 2));
65        int dni = Integer.parseInt(cuitCuilClean.substring(2, 10));
66        int verificationDigit = Integer.parseInt(cuitCuilClean.substring(10, 11));
67        
68        // אמת קוד סוג
69        if (!VALID_TYPE_CODES.contains(typeCode)) {
70            return new ValidationResult(false, "קוד סוג לא תקף");
71        }
72        
73        // חשב והשווה ספרת אימות
74        int calculatedDigit = calculateVerificationDigit(typeCode, dni);
75        if (calculatedDigit != verificationDigit) {
76            return new ValidationResult(false, "ספרת אימות לא תקפה");
77        }
78        
79        return new ValidationResult(true, null);
80    }
81    
82    public static class ValidationResult {
83        private final boolean isValid;
84        private final String errorMessage;
85        
86        public ValidationResult(boolean isValid, String errorMessage) {
87            this.isValid = isValid;
88            this.errorMessage = errorMessage;
89        }
90        
91        public boolean isValid() {
92            return isValid;
93        }
94        
95        public String getErrorMessage() {
96            return errorMessage;
97        }
98    }
99    
100    public static void main(String[] args) {
101        // שימוש לדוגמה
102        System.out.println(generateCuitCuil(20, 12345678)); // צור עבור DNI ספציפי
103        System.out.println(generateCuitCuil(27, null)); // צור עם DNI אקראי
104        System.out.println(validateCuitCuil("20-12345678-9").isValid()); // אמת CUIT/CUIL
105    }
106}
107

PHP

<?php function calculateVerificationDigit($typeCode, $dni) { // המר למחרוזת והבטח שה-DNI הוא 8 ספרות עם אפסים מובילים $typeCodeStr = (string)$typeCode; $dniStr = str_pad((string)$dni, 8, '0', STR_PAD_LEFT); // שלב את קוד הסוג ו-DNI $digits = $typeCodeStr . $dniStr; // משקלות לכל מיקום $weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]; // חשב סכום מכפלות $sumProducts = 0; for ($i = 0; $i < 10; $i++) { $sumProducts += (int)$digits[$i] * $weights[$i]; } // חשב ספרת אימות $verificationDigit = 11 - ($sumProducts % 11); // מקרים מיוחדים if ($verificationDigit == 11) { $verificationDigit = 0; } else if ($verificationDigit == 10) { $verificationDigit = 9; } return $verificationDigit; } function generateCuitCuil($typeCode, $dni = null) { // קודי סוג תקפים $validTypeCodes = [20, 23, 24, 27, 30, 33, 34]; if (!in_array($typeCode, $validTypeCodes)) { throw new Exception("קוד סוג לא תקף. חייב להיות אחד מ: " . implode(', ', $validTypeCodes)); } // צור DNI אקראי אם לא סופק if ($dni === null) { $dni = rand(10000000, 99999999); } // חשב ספרת אימות $verificationDigit = calculateVerificationDigit($typeCode, $dni); // עצב CUIT/CUIL return sprintf("%d-%08d-%d", $typeCode, $dni, $verificationDigit); } function validateCuitCuil($cuitCuil) { // הסר מקפים אם קיימים $cuitCuilClean = str_replace('-', '', $cuitCuil); // בדוק פורמט בסיסי if (!preg_match('/^\d{11}$/', $cuitCuilClean)) { return ['isValid' => false, ## Frequently Asked Questions ### What is the difference between CUIT and CUIL? Here's the practical distinction: **CUIT** (Clave Única de Identificación Tributaria) identifies taxpayers—both individuals and businesses that file taxes with AFIP. **CUIL** (Clave Única de Identificación Laboral) identifies workers in the social security system for employment and retirement purposes. In practice, many individuals have both a CUIL (from their first job) and might later get a CUIT (if they become self-employed or start a business). The numbers use identical formatting and calculation rules, so from a validation standpoint, you handle them the same way. The distinction matters for administrative purposes: payroll systems typically work with CUIL, while invoicing and tax systems use CUIT. ### Which type codes are used for individuals and which for companies? For individuals: - 20, 23, 24: Male individuals (CUIL) - 27: Female individuals (CUIL) For companies and organizations: - 30: Corporations (CUIT) - 33: Civil Associations (CUIT) - 34: Foundations (CUIT) ### How is the verification digit calculated? The algorithm uses weighted multiplication: take each of the first 10 digits, multiply by the weights **5, 4, 3, 2, 7, 6, 5, 4, 3, 2**, sum the products, then calculate 11 minus (sum modulo 11). Two edge cases trip people up: when the calculation yields 11, use 0 as the verification digit; when it yields 10, use 9. These special cases exist because the verification digit must be a single digit (0-9). This is a modulo-11 check digit algorithm, similar to what's used in ISBN-10 codes and other identification systems worldwide. ### Can I use this tool to generate real, official CUIT/CUIL numbers? No—this tool generates mathematically valid test data, but the numbers aren't officially registered with AFIP. Think of it like generating a valid credit card number using the Luhn algorithm: it passes format validation, but it's not connected to a real account. For official CUIT/CUIL registration, individuals need to visit AFIP with their DNI, while businesses must complete corporate registration procedures. The tool is strictly for development, testing, and educational use where you need valid-looking data that won't conflict with real identification numbers. ### Why does my CUIT/CUIL validation fail even though the format looks correct? When validation fails despite correct-looking formatting, check these common culprits: 1. **Invalid type code**: Only 20, 23, 24, 27, 30, 33, 34 are valid. Using 21, 25, or other numbers will fail. 2. **Wrong verification digit**: The last digit must match the algorithm's calculation. Even changing one digit in the DNI portion requires recalculating the check digit. 3. **Format issues**: Must be exactly 11 digits (XX-XXXXXXXX-X). Watch for extra spaces or missing leading zeros. 4. **Hidden characters**: Copy-pasting from PDFs or websites sometimes introduces invisible Unicode characters that break validation. A quick debugging tip: remove the last digit and recalculate it manually. If it doesn't match, that's your culprit. ### Are hyphens required in CUIT/CUIL numbers? Hyphens are for display formatting only—they're not part of the actual number for calculation purposes. When you see **20-12345678-9**, the algorithm only cares about the 11 digits: **20123456789**. Most validation implementations strip hyphens before processing, which is why our tool accepts both **20-12345678-9** and **20123456789**. In APIs and databases, you'll typically store the unhyphenated version and add hyphens only when displaying to users. This approach prevents formatting inconsistencies from causing validation failures. ### Can a CUIT/CUIL number have fewer than 8 digits in the DNI portion? The DNI portion must always be exactly 8 digits—no exceptions. If someone's actual DNI has fewer digits (which happens with older, lower-numbered DNIs), you pad with leading zeros. For example, DNI **1234567** becomes **01234567** in the CUIT/CUIL structure. This is a frequent source of bugs when converting between DNI and CUIT/CUIL formats. I've seen systems fail validation because they forgot to pad, treating **1234567** as a 7-digit number instead of **01234567**. Always use zero-padding functions in your code rather than simple string concatenation. ### How can I verify if a CUIT/CUIL is officially registered in Argentina? Our tool validates the mathematical correctness—format, type code, and check digit. But it can't tell you if the number is actually registered with AFIP or belongs to a real person or business. For official verification, use [AFIP's web services](https://www.afip.gob.ar/) or their "Constancia de Inscripción" lookup tool. AFIP offers APIs for automated verification, though you'll need to register as a developer and authenticate. In production environments, implement both layers: first run algorithmic validation (fast, catches typos and format errors), then verify against AFIP's database (slower, but confirms the number is real and active). ### Can I use this tool in my commercial application? Yes—the CUIT/CUIL validation algorithm is a public standard defined by AFIP, so you can freely implement it in commercial software. The code examples provided here are meant as reference implementations. For production use, consider these best practices: implement proper error handling for edge cases, add logging for debugging validation failures, validate against AFIP's official database (not just algorithmic validation), and keep your implementation up to date if AFIP changes the rules (though the current algorithm has been stable for decades). ### Does the tool store any of the generated or validated CUIT/CUIL numbers? No—all processing happens in your browser (client-side). When you generate or validate a CUIT/CUIL, the calculation runs locally using JavaScript. Nothing gets sent to our servers, and we don't log, store, or track any numbers you enter or generate. This client-side approach ensures privacy and also means the tool works offline once the page loads. You can verify this by opening your browser's developer tools and watching the network tab—you'll see no requests sent when generating or validating numbers. ## מקורות 1. AFIP (הרשות הפדרלית להכנסות ציבוריות). "CUIT/CUIL/CDI." אתר רשמי. [https://www.afip.gob.ar/](https://www.afip.gob.ar/) 2. משרד העבודה, התעסוקה והביטחון החברתי. "CUIL - מפתח זיהוי עבודה יחיד." [https://www.argentina.gob.ar/trabajo](https://www.argentina.gob.ar/trabajo) 3. ANSES (הרשות הלאומית לביטחון סוציאלי). "קבלת CUIL שלי." [https://www.anses.gob.ar/](https://www.anses.gob.ar/) 4. הפרסום הרשמי של הרפובליקה הארגנטינית. "החלטה כללית AFIP 2854/2010: הליך. מפתח זיהוי מס יחיד (C.U.I.T.)." 5. הקוד הפיסקלי של הרפובליקה הארגנטינית. "זיהוי ורישום משלמי מסים." --- בין אם אתה בונה מערכת חשבוניות, בודק תהליכי קליטת עובדים או לומד על אלגוריתמי אימות, כלי זה מספק את יצירת ואימות CUIT/CUIL שאתה צריך. צור נתוני בדיקה שעוברים אימות אלגוריתמי, אמת מספרים לפני שהם מגיעים למסד הנתונים שלך, או חקור כיצד אלגוריתם ספרת הביקורת עובד הלכה למעשה.