מחולל נתוני דמה
מחוללים נתוני דמה שעוברים ולידציה: כרטיסים תקינים לפי Luhn, IBAN עם mod-97, UUID אמיתיים. עם seed לשחזור, כ-JSON, CSV, NDJSON או SQL.
[
{
"id": "018cc251-f400-79a7-abdf-9623646f1963",
"first_name": "Ruby",
"last_name": "Long",
"email": "[email protected]",
"country": "IE",
"created_at": "2024-04-13T08:13:34Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc251-f7e8-7727-8c38-6095cbcabdb9",
"first_name": "Ellen",
"last_name": "Hoffman",
"email": "[email protected]",
"country": "US",
"created_at": "2024-06-28T10:45:21Z",
"last_seen_at": "2024-10-31T16:44:09Z",
"is_active": false
},
{
"id": "018cc251-fbd0-7056-ad40-e80a775668cc",
"first_name": "Keith",
"last_name": "Hudson",
"email": "[email protected]",
"country": "AR",
"created_at": "2025-08-11T01:04:04Z",
"last_seen_at": "2025-09-19T15:18:41Z",
"is_active": true
},
{
"id": "018cc251-ffb8-74a1-b4c8-83cc6bd2ae90",
"first_name": "Thomas",
"last_name": "Moore",
"email": "[email protected]",
"country": "BE",
"created_at": "2025-02-21T16:27:55Z",
"last_seen_at": "2025-04-28T03:30:59Z",
"is_active": true
},
{
"id": "018cc252-03a0-7309-8795-f9f277a8f8c0",
"first_name": "Benjamin",
"last_name": "Austin",
"email": "[email protected]",
"country": "MX",
"created_at": "2024-06-15T11:04:56Z",
"last_seen_at": "2025-06-30T22:00:26Z",
"is_active": true
},
{
"id": "018cc252-0788-7658-937d-58b138c92232",
"first_name": "Barbara",
"last_name": "Flores",
"email": "[email protected]",
"country": "GR",
"created_at": "2024-04-17T19:41:08Z",
"last_seen_at": "2025-01-13T23:55:46Z",
"is_active": true
},
{
"id": "018cc252-0b70-7c3a-96ae-719ee90a05af",
"first_name": "Allen",
"last_name": "Vazquez",
"email": "[email protected]",
"country": "NG",
"created_at": "2024-09-18T13:23:49Z",
"last_seen_at": "2026-05-04T06:32:51Z",
"is_active": false
},
{
"id": "018cc252-0f58-7dfd-8623-52572f04ce20",
"first_name": "Harry",
"last_name": "Nichols",
"email": "[email protected]",
"country": "SG",
"created_at": "2026-06-26T14:48:47Z",
"last_seen_at": "2026-06-30T12:56:13Z",
"is_active": false
},
{
"id": "018cc252-1340-738f-b536-279444cb4512",
"first_name": "Elaine",
"last_name": "Wagner",
"email": "[email protected]",
"country": "UA",
"created_at": "2025-05-09T14:48:44Z",
"last_seen_at": "2026-05-19T14:58:47Z",
"is_active": true
},
{
"id": "018cc252-1728-7d96-8856-b87ee9d904e9",
"first_name": "Fred",
"last_name": "Fisher",
"email": "[email protected]",
"country": "JP",
"created_at": "2025-11-25T05:27:13Z",
"last_seen_at": "2026-04-04T05:36:09Z",
"is_active": true
},
{
"id": "018cc252-1b10-7baa-a79b-9567cf1366fd",
"first_name": "Lois",
"last_name": "Nelson",
"email": "[email protected]",
"country": "FR",
"created_at": "2025-05-08T16:32:25Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-1ef8-7c8c-b859-cea655faef9c",
"first_name": "Mark",
"last_name": "Cunningham",
"email": "[email protected]",
"country": "FI",
"created_at": "2026-02-21T11:09:02Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-22e0-77bf-bc1c-40120a5b29c4",
"first_name": "Anne",
"last_name": "Flores",
"email": "[email protected]",
"country": "KR",
"created_at": "2025-08-02T22:55:20Z",
"last_seen_at": "2025-10-27T03:27:52Z",
"is_active": true
},
{
"id": "018cc252-26c8-7220-9453-1804e8ce88c4",
"first_name": "Arthur",
"last_name": "Crawford",
"email": "[email protected]",
"country": "PL",
"created_at": "2025-02-26T04:55:03Z",
"last_seen_at": "2025-07-25T07:05:17Z",
"is_active": true
},
{
"id": "018cc252-2ab0-75a8-8a2b-28833306b87c",
"first_name": "Ronald",
"last_name": "Hansen",
"email": "[email protected]",
"country": "KR",
"created_at": "2025-03-09T06:31:44Z",
"last_seen_at": "2026-01-04T03:11:24Z",
"is_active": true
},
{
"id": "018cc252-2e98-7c38-93e2-9f80d039eb75",
"first_name": "Donna",
"last_name": "Porter",
"email": "[email protected]",
"country": "IE",
"created_at": "2026-01-12T06:55:22Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-3280-77a0-8152-8f5a9584a581",
"first_name": "Carol",
"last_name": "Wells",
"email": "[email protected]",
"country": "PL",
"created_at": "2025-07-20T23:09:02Z",
"last_seen_at": "2026-01-24T23:04:38Z",
"is_active": true
},
{
"id": "018cc252-3668-7208-8bbe-619dada6b7e0",
"first_name": "Sheila",
"last_name": "Lee",
"email": "[email protected]",
"country": "PT",
"created_at": "2025-01-05T20:09:52Z",
"last_seen_at": "2025-04-08T12:02:09Z",
"is_active": false
},
{
"id": "018cc252-3a50-7b11-9261-0c17e909f6fb",
"first_name": "Jack",
"last_name": "Evans",
"email": "[email protected]",
"country": "KE",
"created_at": "2025-12-29T14:31:00Z",
"last_seen_at": "2026-03-28T14:30:43Z",
"is_active": true
},
{
"id": "018cc252-3e38-7f22-8cc7-0dd649d26379",
"first_name": "Randy",
"last_name": "Harris",
"email": "[email protected]",
"country": "GB",
"created_at": "2026-06-26T19:25:04Z",
"last_seen_at": "2026-06-30T08:39:51Z",
"is_active": true
},
{
"id": "018cc252-4220-7e86-8dae-b25b4f837713",
"first_name": "Josephine",
"last_name": "Castro",
"email": "[email protected]",
"country": "DK",
"created_at": "2024-02-07T22:33:55Z",
"last_seen_at": "2026-02-23T13:56:30Z",
"is_active": true
},
{
"id": "018cc252-4608-7120-abd5-535883ca01b9",
"first_name": "Edith",
"last_name": "Graham",
"email": "[email protected]",
"country": "CN",
"created_at": "2024-04-29T08:59:26Z",
"last_seen_at": "2024-06-17T10:20:45Z",
"is_active": true
},
{
"id": "018cc252-49f0-77f7-9bf9-17e87b0a09c6",
"first_name": "Tracy",
"last_name": "Willis",
"email": "[email protected]",
"country": "PT",
"created_at": "2024-03-21T07:42:06Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-4dd8-75c8-8b04-1e0fb891e435",
"first_name": "Irene",
"last_name": "Larson",
"email": "[email protected]",
"country": "AT",
"created_at": "2025-06-04T15:01:38Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-51c0-7be0-a6ca-12bc704a2b3f",
"first_name": "Betty",
"last_name": "Morrison",
"email": "[email protected]",
"country": "ID",
"created_at": "2025-11-11T21:56:19Z",
"last_seen_at": "2026-03-29T03:33:49Z",
"is_active": true
},
{
"id": "018cc252-55a8-736d-a7b2-8bec744ecf74",
"first_name": "Kevin",
"last_name": "Cox",
"email": "[email protected]",
"country": "GR",
"created_at": "2025-10-06T23:28:21Z",
"last_seen_at": null,
"is_active": false
},
{
"id": "018cc252-5990-73ca-a2d3-89bf2b8eb5f6",
"first_name": "Sean",
"last_name": "Carr",
"email": "[email protected]",
"country": "KR",
"created_at": "2026-02-19T23:27:53Z",
"last_seen_at": "2026-03-02T22:16:30Z",
"is_active": true
},
{
"id": "018cc252-5d78-79e2-bd4d-d8b6867867dc",
"first_name": "Heather",
"last_name": "Ferguson",
"email": "[email protected]",
"country": "IL",
"created_at": "2024-07-07T01:39:16Z",
"last_seen_at": "2025-09-21T19:17:00Z",
"is_active": false
},
{
"id": "018cc252-6160-78f8-a9af-d73b74581b86",
"first_name": "Rose",
"last_name": "Chen",
"email": "[email protected]",
"country": "DE",
"created_at": "2024-09-07T16:16:48Z",
"last_seen_at": "2024-10-02T08:29:39Z",
"is_active": true
},
{
"id": "018cc252-6548-71f0-ab4f-c824fd842a67",
"first_name": "Maria",
"last_name": "Brooks",
"email": "[email protected]",
"country": "FR",
"created_at": "2024-06-29T06:22:30Z",
"last_seen_at": "2025-12-22T00:38:13Z",
"is_active": true
},
{
"id": "018cc252-6930-7067-b516-480051493ec0",
"first_name": "Donna",
"last_name": "Hamilton",
"email": "[email protected]",
"country": "IE",
"created_at": "2024-09-01T09:09:40Z",
"last_seen_at": "2025-03-29T23:26:22Z",
"is_active": false
},
{
"id": "018cc252-6d18-7de1-bae1-21dc471405fa",
"first_name": "Rachel",
"last_name": "Wagner",
"email": "[email protected]",
"country": "IE",
"created_at": "2026-05-31T02:06:02Z",
"last_seen_at": "2026-06-17T16:37:27Z",
"is_active": false
},
{
"id": "018cc252-7100-752d-bc4e-c4e5bd755743",
"first_name": "Philip",
"last_name": "Jones",
"email": "[email protected]",
"country": "NO",
"created_at": "2024-10-21T12:22:35Z",
"last_seen_at": "2025-02-15T07:00:10Z",
"is_active": true
},
{
"id": "018cc252-74e8-7b4d-b9cf-4e8e03d1e269",
"first_name": "Bonnie",
"last_name": "Carter",
"email": "[email protected]",
"country": "PT",
"created_at": "2026-05-28T06:16:25Z",
"last_seen_at": "2026-06-26T21:36:12Z",
"is_active": true
},
{
"id": "018cc252-78d0-708b-a96f-d9f474e95238",
"first_name": "Douglas",
"last_name": "Evans",
"email": "[email protected]",
"country": "NG",
"created_at": "2024-02-18T20:36:33Z",
"last_seen_at": "2024-10-31T01:37:50Z",
"is_active": true
},
{
"id": "018cc252-7cb8-7865-96fa-e9681611dbed",
"first_name": "Theresa",
"last_name": "Larson",
"email": "[email protected]",
"country": "NZ",
"created_at": "2024-11-21T08:57:18Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-80a0-7eca-80cd-7159faf3467f",
"first_name": "Gladys",
"last_name": "Reyes",
"email": "[email protected]",
"country": "NG",
"created_at": "2024-04-27T11:34:46Z",
"last_seen_at": "2026-03-09T18:39:31Z",
"is_active": true
},
{
"id": "018cc252-8488-76b2-9271-dabf0da27b4f",
"first_name": "Bonnie",
"last_name": "Cook",
"email": "[email protected]",
"country": "AT",
"created_at": "2024-01-13T17:42:35Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-8870-70d0-ab33-72cd838e6603",
"first_name": "Diane",
"last_name": "Wells",
"email": "[email protected]",
"country": "NZ",
"created_at": "2024-05-02T11:22:23Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-8c58-725c-980d-f206b971497b",
"first_name": "Gloria",
"last_name": "Woods",
"email": "[email protected]",
"country": "IT",
"created_at": "2025-06-27T01:56:54Z",
"last_seen_at": "2025-09-04T17:13:00Z",
"is_active": true
},
{
"id": "018cc252-9040-786d-90d1-5c9bae512dbf",
"first_name": "Alan",
"last_name": "Rodriguez",
"email": "[email protected]",
"country": "DK",
"created_at": "2026-03-29T17:48:08Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-9428-7b58-8dde-508b603b97d8",
"first_name": "Leonard",
"last_name": "Jones",
"email": "[email protected]",
"country": "MX",
"created_at": "2026-02-06T22:38:18Z",
"last_seen_at": "2026-04-27T00:46:32Z",
"is_active": true
},
{
"id": "018cc252-9810-7c69-8024-23852691d72c",
"first_name": "Maria",
"last_name": "Davis",
"email": "[email protected]",
"country": "JP",
"created_at": "2025-03-30T14:01:05Z",
"last_seen_at": "2025-04-24T10:25:01Z",
"is_active": true
},
{
"id": "018cc252-9bf8-7e3a-a37a-06b1a661a0dc",
"first_name": "Carl",
"last_name": "Duncan",
"email": "[email protected]",
"country": "KE",
"created_at": "2026-03-30T06:02:52Z",
"last_seen_at": "2026-05-16T00:15:55Z",
"is_active": false
},
{
"id": "018cc252-9fe0-7a01-8a38-5d3e36f9eca3",
"first_name": "Phillip",
"last_name": "Harrison",
"email": "[email protected]",
"country": "DK",
"created_at": "2024-07-12T01:56:26Z",
"last_seen_at": "2026-05-28T21:32:17Z",
"is_active": true
},
{
"id": "018cc252-a3c8-7977-a212-1c82b978ccbe",
"first_name": "Kim",
"last_name": "Franklin",
"email": "[email protected]",
"country": "KE",
"created_at": "2024-09-23T15:16:03Z",
"last_seen_at": "2025-08-20T03:29:07Z",
"is_active": true
},
{
"id": "018cc252-a7b0-78f6-bb2a-d194bc638e71",
"first_name": "Patrick",
"last_name": "Coleman",
"email": "[email protected]",
"country": "ID",
"created_at": "2025-01-06T09:04:26Z",
"last_seen_at": "2025-07-21T22:36:07Z",
"is_active": true
},
{
"id": "018cc252-ab98-7b5b-8f5c-8b6a21b71208",
"first_name": "Harry",
"last_name": "Martin",
"email": "[email protected]",
"country": "ES",
"created_at": "2026-02-21T17:42:10Z",
"last_seen_at": "2026-05-16T20:52:12Z",
"is_active": true
},
{
"id": "018cc252-af80-7504-8719-59c6e3efd9c3",
"first_name": "Carlos",
"last_name": "Gibson",
"email": "[email protected]",
"country": "ZA",
"created_at": "2024-01-14T06:39:34Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-b368-7525-9a9c-a09c2f8c2c8b",
"first_name": "Jean",
"last_name": "Morales",
"email": "[email protected]",
"country": "CA",
"created_at": "2025-06-05T13:13:54Z",
"last_seen_at": "2025-07-18T07:30:36Z",
"is_active": true
},
{
"id": "018cc252-b750-76bd-81cc-42435c3231bd",
"first_name": "Ernest",
"last_name": "Cooper",
"email": "[email protected]",
"country": "FR",
"created_at": "2026-06-30T05:15:30Z",
"last_seen_at": "2026-06-30T22:07:31Z",
"is_active": true
},
{
"id": "018cc252-bb38-7a65-8fdd-29417173ce08",
"first_name": "John",
"last_name": "Wallace",
"email": "[email protected]",
"country": "GR",
"created_at": "2024-01-01T11:53:11Z",
"last_seen_at": "2025-05-13T01:10:51Z",
"is_active": false
},
{
"id": "018cc252-bf20-7253-a075-e01c6d997ffd",
"first_name": "Lee",
"last_name": "Brooks",
"email": "[email protected]",
"country": "AU",
"created_at": "2024-03-20T07:03:24Z",
"last_seen_at": "2025-04-29T10:30:14Z",
"is_active": true
},
{
"id": "018cc252-c308-7709-a61e-916f4cb44f86",
"first_name": "Antonio",
"last_name": "Evans",
"email": "[email protected]",
"country": "JP",
"created_at": "2025-09-17T01:49:49Z",
"last_seen_at": "2026-04-27T19:54:08Z",
"is_active": true
},
{
"id": "018cc252-c6f0-7095-be95-c60913b0062d",
"first_name": "Jose",
"last_name": "Porter",
"email": "[email protected]",
"country": "ZA",
"created_at": "2024-06-01T00:33:54Z",
"last_seen_at": "2024-09-30T08:59:58Z",
"is_active": false
},
{
"id": "018cc252-cad8-7565-b5d8-117f4a6fb217",
"first_name": "Eric",
"last_name": "Ward",
"email": "[email protected]",
"country": "TR",
"created_at": "2024-03-06T08:01:45Z",
"last_seen_at": "2024-10-07T12:38:03Z",
"is_active": true
},
{
"id": "018cc252-cec0-79ae-adaa-96058dd4aabe",
"first_name": "Marjorie",
"last_name": "Cox",
"email": "[email protected]",
"country": "NG",
"created_at": "2026-06-08T11:01:04Z",
"last_seen_at": "2026-06-20T16:41:37Z",
"is_active": true
},
{
"id": "018cc252-d2a8-7d31-bab8-63bfaa7342bd",
"first_name": "Bryan",
"last_name": "Pena",
"email": "[email protected]",
"country": "IT",
"created_at": "2024-01-06T14:25:41Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-d690-7e1b-a275-f48a8c1ccbf6",
"first_name": "Catherine",
"last_name": "Munoz",
"email": "[email protected]",
"country": "AU",
"created_at": "2026-05-30T07:29:25Z",
"last_seen_at": "2026-06-23T08:23:39Z",
"is_active": true
},
{
"id": "018cc252-da78-7c22-9180-f137d46ec702",
"first_name": "Joyce",
"last_name": "Jordan",
"email": "[email protected]",
"country": "TR",
"created_at": "2025-01-13T19:52:26Z",
"last_seen_at": null,
"is_active": true
},
{
"id": "018cc252-de60-7bc5-907f-8eebca9226bf",
"first_name": "Jennifer",
"last_name": "Riley",
"email": "[email protected]",
"country": "AT",
"created_at": "2026-02-21T06:27:48Z",
"last_seen_at": "2026-04-30T10:23:57Z",
"is_active": true
},
{
"id": "018cc252-e248-7464-86b7-54ee11fc6051",
"first_name": "Amanda",
"last_name": "Daniels",
"email": "[email protected]",
"country": "IL",
"created_at": "2025-04-29T02:18:30Z",
"last_seen_at": "2026-04-17T18:37:07Z",
"is_active": false
},
{
"id": "018cc252-e630-7bf3-ab8d-a72175e7c3fb",
"first_name": "Laura",
"last_name": "Alvarado",
"email": "[email protected]",
"country": "PT",
"created_at": "2024-08-26T17:26:51Z",
"last_seen_at": "2025-09-16T12:46:07Z",
"is_active": true
},
{
"id": "018cc252-ea18-74fb-955a-5d6d42ed1760",
"first_name": "Andrea",
"last_name": "Turner",
"email": "[email protected]",
"country": "CA",
"created_at": "2024-07-13T08:04:19Z",
"last_seen_at": "2025-01-08T17:24:13Z",
"is_active": true
},
{
"id": "018cc252-ee00-7216-953a-2094b3402b1e",
"first_name": "Margaret",
"last_name": "Jackson",
"email": "[email protected]",
"country": "NZ",
"created_at": "2025-07-14T00:05:54Z",
"last_seen_at": "2026-05-05T09:44:04Z",
"is_active": true
},
{
"id": "018cc252-f1e8-7262-91aa-5818265220ca",
"first_name": "Rose",
"last_name": "Johnson",
"email": "[email protected]",
"country": "KR",
"created_at": "2024-07-18T02:49:21Z",
"last_seen_at": "2025-04-18T08:52:53Z",
"is_active": true
},
{
"id": "018cc252-f5d0-72f1-ba49-a52514f881dd",
"first_name": "Fred",
"last_name": "George",
"email": "[email protected]",
"country": "PL",
"created_at": "2025-10-26T23:11:53Z",
"last_seen_at": "2025-11-05T21:15:27Z",
"is_active": true
},
{
"id": "018cc252-f9b8-7173-b05d-540124a4fc47",
"first_name": "Sara",
"last_name": "Greene",
"email": "[email protected]",
"country": "PT",
"created_at": "2026-04-26T10:11:22Z",
"last_seen_at": "2026-05-07T04:01:08Z",
"is_active": true
},
{
"id": "018cc252-fda0-7ed5-a24a-3f179c69fc3c",
"first_name": "Jesse",
"last_name": "Bennett",
"email": "[email protected]",
"country": "SG",
"created_at": "2025-10-08T16:19:51Z",
"last_seen_at": "2026-03-04T05:50:50Z",
"is_active": true
},
{
"id": "018cc253-0188-74dd-a728-ed228fc827ac",
"first_name": "Louise",
"last_name": "Santos",
"email": "[email protected]",
"country": "FI",
"created_at": "2026-05-29T18:38:35Z",
"last_seen_at": "2026-06-01T15:33:29Z",
"is_active": true
},
{
"id": "018cc253-0570-7408-b582-07fbebeacbbf",
"first_name": "Scott",
"last_name": "Grant",
"email": "[email protected]",
"country": "NZ",
"created_at": "2024-02-11T17:35:11Z",
"last_seen_at": "2025-08-06T23:23:49Z",
"is_active": true
},
{
"id": "018cc253-0958-7c12-b38e-edc7af958916",
"first_name": "Judy",
"last_nמוצגים 20000 התווים הראשונים מתוך 28086. ההעתקה וההורדה לוקחות את הכול.
הדואר הולך ל-example.com, הטלפונים לבלוק 555-0100, הכתובות לרשתות התיעוד והכרטיסים למספרי BIN שפורסמו לבדיקה — כל ברירת מחדל כאן היא טווח שתקן שומר, ולכן שום דבר שנוצר כאן לא יכול להיות שייך לאדם אמיתי.
נתונים שעוברים את הוולידטורים שלכם
התלונה הרגילה על נתוני בדיקה שנוצרו אוטומטית אינה שהם נראים מזויפים. היא שהם נופלים. מספר כרטיס ששום ספריית תשלומים לא תקבל, IBAN שטופס בנקאי פוסל, ISBN שקורא ברקוד לא מצליח לקרוא, UUID שספרת הגרסה שלו היא פשוט מה שהבייטים האקראיים הזדמנו להיות. בסוף עורכים את ה-fixture ביד, ובנקודה הזו המחולל עלה יותר ממה שחסך.
כל ערך כאן שתקן שפורסם מגדיר לו בדיקה נושא את הבדיקה הנכונה. זו כמות קטנה של חשבון, והיא משנה את מה שהנתונים משמשים לו: אפשר להפנות אליהם את הוולידציה האמיתית שלכם.
- מספרי כרטיסים נושאים את ספרת הביקורת של Luhn לפי ISO/IEC 7812-1, מחושבת על הספרות שלפניה, ויושבים על מספר ה-BIN שפורסם כמספר בדיקה של המותג שבחרתם.
- מספרי IBAN מקיימים את ISO 7064 mod-97 — ספרות הביקורת נבחרות כך שהמספר המסודר מחדש והמורחב לאותיות משאיר שארית 1 — והם באורך המדויק שהמדינה רושמת, מה ש-mod-97 לבדו לא היה תופס.
- ערכי ISBN-13 ו-EAN-13 נושאים את ספרת הביקורת במשקלות המתחלפים 1 ו-3, תחת אחת משתי הקידומות של GS1 שהוקצו למערכת ה-ISBN.
- למספרי UUID יש את ספרת הגרסה ואת שני ביטי הווריאנט ש-RFC 9562 דורש, ולכן מנתח מדווח v4 או v7 במקום למשוך בכתפיים.
- כתובות, חותמות זמן, גרסאות סמנטיות וקודי מטבע כתובים בצורה שהתקן שלהם מגדיר, ולא בקירוב שלה.
שום דבר מזה לא הופך את הנתונים לאמיתיים. זה הופך אותם לתקינים מבחינה צורנית, וזו התכונה היחידה ש-fixture יכול לטעון לה ביושר.
ה-seed, ולמה הוא כל העניין
מחולל שנותן לכם שורות אחרות בכל פעם הוא צעצוע. ברגע שהנתונים נכנסים לבדיקה, להדגמה או לצילום מסך, אתם צריכים להיות מסוגלים להחזיר אותם — אחרי רענון, במחשב של עמית, ב-CI בעוד שנה.
לכן האקראיות כאן זרועה ב-seed. ה-seed הוא מחרוזת שאתם בוחרים, ואותו seed עם אותה סכימה ואותו מספר שורות מייצר פלט זהה בייט-בבייט בכל מקום. המחולל הוא xoshiro128**, נזרע דרך splitmix64; שניהם אלגוריתמים שפורסמו עם מימושי ייחוס, והדף הזה נבדק מול פלט שהועתק מהמימושים האלה ולא מול עצמו.
seed "orders-2026" same rows, every time, everywhere seed "orders-2027" a completely different set field stream = hash(seed, field name) row N of a field depends on nothing but the seed, the name and N
את השורה האחרונה כדאי לקרוא פעמיים, כי היא זו שהופכת את הכלי לשימושי ולא רק לניתן לשחזור. כל שדה שואב מזרם משלו, לפי שמו. מוסיפים עמודה וכל העמודות הקיימות יוצאות זהות. מגדילים את מספר השורות ממאה לאלף ומאה השורות הראשונות הן אלה שכבר היו לכם. fixture ששמרתם אתמול עדיין מתאים אחרי שהרחבתם את הסכימה היום.
המחיר ההוגן של הזריעה לפי השם הוא ששינוי שם של שדה מחליף את הנתונים שלו, כי השם הוא חצי מה-seed. שיעור הריקים הוא ההגדרה היחידה שפטורה מזה בכוונה: ההחלטה לרוקן ערך מתקבלת אחרי שהערך נשלף, ולכן הפעלת ריקים מוחקת חלק מהשורות בלי להזיז את השאר.
אזהרה אחת נובעת ישירות מכל זה. מחולל עם seed הוא צפוי מעצם הגדרתו — זו התכונה. אסור להשתמש בשום דבר שהוא מייצר כסיסמה, כאסימון או כמפתח. לאלה השתמשו במחולל ששואב ממקור האקראיות הקריפטוגרפי של הפלטפורמה.
טווחים שנשמרו כדי שהנתונים שלכם לא יוכלו להיות אמיתיים
מחולל שפולט כתובות בדומיין דואר אמיתי מוסר לכם אקדח טעון. חבילות בדיקה שולחות דואר. סביבות staging מכוונות בטעות ל-SMTP של הייצור. בדיקות עומס מפציצות את כתובת ה-IP שכתובה ב-fixture. כשהערך שייך למישהו, התאונה מגיעה אליו.
גופי התקינה צפו את זה והפרישו טווחים שמובטח שלעולם לא יוקצו. כל ברירת מחדל כאן שואבת מאחד מהם:
- דואר נוחת ב-example.com, ב-example.net וב-example.org, ש-RFC 2606 שומר לצמיתות, לצד סיומות העל .test, .example ו-.invalid ש-RFC 6761 מוסיף.
- מספרי טלפון משתמשים ב-555-0100 עד 555-0199, הבלוק שמערכת המספור של צפון אמריקה שומרת לבדיון — ולכן סרטים משתמשים בו.
- כתובות IPv4 מגיעות מ-192.0.2.0/24, מ-198.51.100.0/24 ומ-203.0.113.0/24, שלוש רשתות התיעוד של RFC 5737, וכתובות IPv6 מ-2001:db8::/32 לפי RFC 3849.
- כתובות MAC מדליקות את ביט הניהול המקומי, ש-IEEE מתחייב לעולם לא להקצות; גם בלוק התיעוד של RFC 7042 מוצע, אף שיש בו 256 כתובות בלבד.
- מספרי כרטיסים נבנים על ארבעת מספרי ה-BIN שפורסמו לבדיקה ולא על טווח הנפקה חי, ולכן מספר תקין לפי Luhn אינו יכול להיתקל בכרטיס אמיתי.
כל אחד מאלה ניתן לעקיפה כשיש לכם סיבה — דומיין משלכם לסביבת staging, בלוק CIDR שתואם לרשת שלכם. ברירת המחדל היא התשובה הבטוחה, והעקיפה נשארת החלטה מודעת שלכם.
השמות והמקומות נשאבים מהתפלגויות השמות שלשכת המפקד של ארצות הברית מפרסמת ומרשימת היישובים המאוגדים שלה. אלה שמות אנגליים נפוצים, כלומר שם שנוצר כאן עשוי להתלכד עם שם של אדם אמיתי — כמו שכל שם עשוי. התייחסו לפלט כאל מה שהוא: מחרוזות סבירות, לא אנשים.
שדות שמפנים זה לזה
עמודות בלתי תלויות מייצרות שורות שמתפרקות במבט. משתמשת בשם דנה לוי שכתובת האימייל שלה אינה קשורה לשמה נראית שבורה בצילום מסך, וחותמת עדכון שקודמת לחותמת היצירה תפיל בדיקה אמיתית.
במקום מקרה פרטי לכל צמד יש מנגנון אחד: כל הגדרה שמסומנת כמקבלת הפניות יכולה לנקוב בשם של שדה אחר בין סוגריים מסולסלים כפולים, והוא מולא מאותה שורה. השדות נוצרים אז בסדר התלות ולא בסדר שבו רשמתם אותם, ומעגל של הפניות מדווח כשגיאת סכימה במקום להיתקע.
זה מגיע רחוק יותר מאימיילים. שדה תבנית בונה כל מחרוזת שתרצו מתוך עמודות אחרות, עם המרת אותיות אופציונלית. הגבול התחתון או העליון של שדה תאריך יכול לנקוב בשם של שדה תאריך אחר, וכך מקבלים ציר זמן שמחזיק מים. וכשערך שהופנו אליו הוא ריק, גם השדה שתלוי בו ריק, במקום ליפול בשקט חזרה לחלון ברירת מחדל שהסכימה מעולם לא הזכירה.
להוציא את זה החוצה: JSON, NDJSON, CSV, SQL
JSON הוא המובן מאליו ויוצא עם הזחה או בשורה אחת. NDJSON — אובייקט דחוס אחד בכל שורה — הוא מה שצינורות לוג ומייבאי הזרמה מצפים לו, וזה הפורמט להדביק בכלי שקורא רשומה בכל פעם.
פורמט CSV נכתב לפי RFC 4180: שדות מצוטטים רק כשהם מכילים פסיק, מרכאה או מעבר שורה, מרכאה פנימית מוכפלת, והשורות מסתיימות ב-CRLF. זו הצורה שגיליונות אלקטרוניים ומטעיני נתונים של מסדי נתונים מסכימים עליה.
ב-SQL מחוללים בדרך כלל מתרשלים, כי התשובה הנכונה תלויה בדיאלקט. ציטוט מזהים שונה — PostgreSQL ו-SQLite מקבלים מרכאות כפולות, MySQL מקבל גרשי הפוך, ו-SQL Server מקבל סוגריים מרובעים — וכל אחד מכפיל את תו הציטוט שלו בתוך שם. מחרוזות מכפילות את הגרש הבודד בכל מקום, אבל MySQL קורא גם לוכסן אחורי כתו בריחה אלא אם NO_BACKSLASH_ESCAPES דלוק, ולכן נתיב Windows שמסתיים בלוכסן היה בולע את הגרש הסוגר. בוליאנים הם הפיצול השלישי: ל-PostgreSQL יש טיפוס בוליאני אמיתי והאחרים רוצים 1 ו-0. ו-SQL Server מסרב לבנאי טבלת ערכים עם יותר מאלף שורות, ולכן ייצוא גדול נפלט כמה פקודות במקום אחת שנכשלת.
PostgreSQL INSERT INTO "records" ("id", "ok") VALUES (1, TRUE);
MySQL INSERT INTO `records` (`id`, `ok`) VALUES (1, 1);
SQLite INSERT INTO "records" ("id", "ok") VALUES (1, 1);
SQL Server INSERT INTO [records] ([id], [ok]) VALUES (1, 1);הסכימה היא קובץ
הפאנל שליד הבונה הוא אותה סכימה כתובה כ-JSON, והוא עובד בשני הכיוונים: עורכים את השדות והוא מתעדכן, מדביקים סכימה והבונה עוקב. הגדרות שנשארו בברירת המחדל מושמטות, כך שמה שקוראים בחזרה הוא ההחלטות שקיבלתם ולא כל בורג שיש לכלי.
הקובץ הזה, יחד עם ה-seed שבתוכו, הוא יחידת השחזור השלמה. שמרו אותו לצד הבדיקה שצורכת את הנתונים וה-fixture הופך למשהו שסוקר יכול לקרוא ועמית יכול לייצר מחדש, במקום גוש גדול של ערכים שאיש לא יודע להסביר.
שאלות נפוצות
- מספרי כרטיסי האשראי אמיתיים?
- הם תקינים והם לא אמיתיים. כל אחד נושא ספרת ביקורת Luhn נכונה, ולכן ספריית תשלומים תקבל את הפורמט שלו, וכל אחד בנוי על אחד מארבעת מספרי ה-BIN שפורסמו לבדיקה ולא על טווח הנפקה חי, ולכן הוא לא יכול להתלכד עם כרטיס שמישהו מחזיק. הם לא יאשרו תשלום בשום מקום.
- אותו seed באמת ייתן לי את אותם נתונים בשנה הבאה?
- כן. המחולל הוא אלגוריתם שפורסם עם מימוש ייחוס קבוע, ולא ממשק של דפדפן שהתנהגותו יכולה להשתנות, והדף הזה נבדק מול פלט שהועתק מאותו מימוש. שום דבר לא קורא את השעון: טווחי התאריכים הם ערכים מפורשים בסכימה. שמרו את סכימת ה-JSON ואת ה-seed שבתוכה והשורות חוזרות בדיוק.
- למה הוספת עמודה לא שינתה שום דבר אחר?
- כי כל שדה שואב מזרם משלו, לפי ה-seed ושם השדה. זה מכוון: fixture שמתערבב מחדש בכל פעם שמרחיבים את הסכימה הוא כזה שאי-אפשר להחזיק ב-repo. אותה תכונה גורמת לכך שהגדלת מספר השורות משאירה את השורות הקודמות בשלמותן.
- שיניתי שם של שדה והנתונים שלו השתנו.
- זה נובע מאותו עיצוב — שם השדה הוא חצי ממפתח הזרם שלו. אם אתם רוצים לשמור את הערכים, שנו את שם העמודה בהמשך הצינור, או קבלו את השליפה החדשה. אין דרך לקבל גם יציבות בשינוי שם וגם יציבות בשינוי סדר בלי מזהה נסתר שקובץ הסכימה היה צריך לשאת.
- אפשר לייצר בזה סיסמה או מפתח API?
- לא. הכול כאן מגיע ממחולל פסאודו-אקראי זרוע ב-seed, שהוא צפוי מעצם הגדרתו וזו הסיבה שהפלט ניתן לשחזור. סוד חייב להגיע ממקור האקראיות הקריפטוגרפי של הפלטפורמה. השתמשו במחולל אסימונים ייעודי לשם כך.
- איך גורמים לאימייל להתאים לשם?
- הוסיפו שדה תבנית וכתבו את שמות העמודות האחרות בין סוגריים מסולסלים כפולים — משהו כמו {{first_name}}.{{last_name}}@example.com — ואז הגדירו את המרת האותיות לאותיות קטנות. השדות נוצרים בסדר התלות, ולכן התבנית יכולה לנקוב בעמודה שמופיעה אחריה ברשימה.
- כמה שורות אפשר לייצר?
- עשרת אלפים, על פני עד ארבעים שדות. הייצור מהיר מספיק כדי להישאר על התהליכון הראשי בגודל הזה; מה שבאמת נעשה לא נוח הוא הטקסט שיוצא, ולכן הפאנל מציג תצוגה מקוצרת בעוד ההעתקה וההורדה לוקחות את הכול.
- משהו מזה יוצא מהדפדפן שלי?
- לא. המחולל, מאגר השמות וכל פורמטי הפלט רצים כ-JavaScript בדף. אין שום קריאה לשרת, ושום דבר שאתם מקלידים בסכימה לא נשלח לשום מקום.