{"id":32522091,"url":"https://github.com/gregorykogan/file-scanner","last_synced_at":"2026-07-03T22:32:31.609Z","repository":{"id":315828913,"uuid":"1060371174","full_name":"GregoryKogan/file-scanner","owner":"GregoryKogan","description":"A comprehensive C++ project demonstrating modern software engineering principles, implemented as a multithreaded malicious file scanner for a Kaspersky internship assignment.","archived":false,"fork":false,"pushed_at":"2025-09-30T16:05:46.000Z","size":97,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-28T06:52:24.825Z","etag":null,"topics":["c-plus-plus","clean-architecture","cmake","command-line-tool","concurrency","cpp","cpp17","cross-platform","doxygen","googletest","md5","multithreading","portfolio-project","scanner","security","solid-principles"],"latest_commit_sha":null,"homepage":"https://gregorykogan.github.io/file-scanner/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GregoryKogan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-19T19:53:31.000Z","updated_at":"2025-09-30T16:05:50.000Z","dependencies_parsed_at":"2025-09-21T02:37:15.775Z","dependency_job_id":"f16394ba-99fc-4b9f-a222-e45f9a2642d1","html_url":"https://github.com/GregoryKogan/file-scanner","commit_stats":null,"previous_names":["gregorykogan/file-scanner"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/GregoryKogan/file-scanner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregoryKogan%2Ffile-scanner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregoryKogan%2Ffile-scanner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregoryKogan%2Ffile-scanner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregoryKogan%2Ffile-scanner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GregoryKogan","download_url":"https://codeload.github.com/GregoryKogan/file-scanner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregoryKogan%2Ffile-scanner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35104113,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-03T02:00:05.635Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-plus-plus","clean-architecture","cmake","command-line-tool","concurrency","cpp","cpp17","cross-platform","doxygen","googletest","md5","multithreading","portfolio-project","scanner","security","solid-principles"],"created_at":"2025-10-28T06:51:37.658Z","updated_at":"2026-07-03T22:32:31.585Z","avatar_url":"https://github.com/GregoryKogan.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# File Scanner\n\n[![C++ CI](https://github.com/GregoryKogan/file-scanner/actions/workflows/ci.yml/badge.svg)](https://github.com/GregoryKogan/file-scanner/actions/workflows/ci.yml)\n[![Coverage](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgist.githubusercontent.com%2FGregoryKogan%2F923bd3f3a429d54421ddb17eb8e99852%2Fraw%2Ffile-scanner-coverage.json\u0026query=message\u0026label=coverage\u0026logo=c%2B%2B\u0026color=green)](https://gist.github.com/GregoryKogan/923bd3f3a429d54421ddb17eb8e99852)\n[![Docs](https://img.shields.io/badge/Docs-latest-blue.svg)](https://GregoryKogan.github.io/file-scanner/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\nA high-performance, multithreaded command-line utility for scanning files against a database of malicious MD5 hashes.\n\nThis project is a demonstration of modern C++ software engineering principles, designed to be robust, scalable, and maintainable. It is built with a clean, decoupled architecture to ensure high cohesion, low coupling, and excellent testability.  \n\n\u003e Made for the [Kaspersky SafeBoard](safeboard.kaspersky.ru) internship.\n\n## Features\n\n- **High-Performance \u0026 Concurrent:** Utilizes all available CPU cores to hash files in parallel, capable of scanning hundreds of thousands of files per minute.\n- **Scalable:** Employs a streaming approach to calculate MD5 hashes, allowing it to process files of any size (even those larger than available RAM) without performance degradation.\n- **Clean Architecture:** Strictly separates concerns into Domain, Application, and Infrastructure layers. This makes the core logic independent of external details like filesystems and databases.\n- **Modern C++:** Written in C++17, leveraging modern features like smart pointers, `std::filesystem`, `std::thread`, atomics, and move semantics.\n- **Fully Tested:** Includes a comprehensive suite of unit and integration tests using the Google Test framework to ensure correctness and reliability.\n- **CI/CD:** Features a complete Continuous Integration pipeline using GitHub Actions for automated cross-platform builds (Windows, macOS, Linux), testing, code coverage analysis, and documentation deployment.\n- **Well-Documented:** Provides a full API reference generated by Doxygen and hosted on GitHub Pages.\n\n## Performance\n\nThe scanner is designed for high throughput on modern hardware. Benchmarks were conducted on a machine equipped with an Apple M1 Pro (8 performance cores).\n\nThe benchmark consists of scanning a directory containing **100,000 files** (1KB to 128KB each) with a total size of approximately 6.5 GB.\n\n| Metric                 | Result                |\n| ---------------------- | --------------------- |\n| **Total Execution Time** | **~19.1 seconds**     |\n| **Throughput**         | **~5200 files/second** |\n\n\u003e ~750 files/second for the single threaded version (7x slower)\n\nDuring the scan, the utility successfully utilizes all available CPU cores, demonstrating the efficiency of the multithreaded architecture.\n\nTo run the benchmark on your own machine, use the `benchmark` target:\n\n```bash\ncmake --build build --target benchmark\n```\n\n## Requirements\n\n- **CMake** (version 3.14 or higher)\n- **A C++17 compliant compiler** (e.g., GCC 9+, Clang 10+, MSVC 2019+)\n- **Python 3** (for running the performance benchmark)\n- **Doxygen \u0026 Graphviz** (optional, for generating documentation locally)\n\n## Building and Testing\n\nThe project uses a standard CMake workflow. All C++ dependencies (Google Test, md5-lib) are fetched automatically.\n\n```bash\n# 1. Clone the repository\ngit clone https://github.com/GregoryKogan/file-scanner.git\ncd file-scanner\n\n# 2. Configure the project\ncmake -S . -B build\n\n# 3. Build all targets (library, executable, tests)\ncmake --build build\n\n# 4. Run all unit and integration tests\nctest --test-dir build --output-on-failure\n```\n\n## Usage\n\nThe utility is run from the command line with three required arguments.\n\n**Launch Command:**\n\n```bash\n# From the 'build' directory after compiling\n./bin/scanner --path /path/to/scan --base /path/to/database.csv --log /path/to/report.log\n```\n\n**Arguments:**\n\n- `--path \u003cdirectory\u003e`: The absolute or relative path to the root directory to be scanned.\n- `--base \u003cfile.csv\u003e`: The path to the CSV file containing malicious signatures.\n- `--log \u003cfile.log\u003e`: The path to the file where detection reports will be written.\n\n### Example `base.csv` Format\n\nThe signature database is a simple text file with one entry per line. Each line contains an MD5 hash and a verdict, separated by a semicolon.\n\n```csv\na9963513d093ffb2bc7ceb9807771ad4;Exploit\nac6204ffeb36d2320e52f1d551cfa370;Dropper\n```\n\n### Example `report.log` Output\n\nDetections are logged in the JSON Lines (JSONL) format, which is structured and machine-readable.\n\n```json\n{\"path\": \"/path/to/scan/bad_file1.exe\", \"hash\": \"a9963513d093ffb2bc7ceb9807771ad4\", \"verdict\": \"Exploit\"}\n{\"path\": \"/path/to/scan/nested/bad_file2.dll\", \"hash\": \"ac6204ffeb36d2320e52f1d551cfa370\", \"verdict\": \"Dropper\"}\n```\n\n### Example Console Report\n\nAfter the scan is complete, a summary is printed to the console.\n\n```shell\n--- Scan Report ---\nProcessed files: 15032\nMalicious detections: 2\nErrors: 1\nExecution time: 3451 ms\n-------------------\n```\n\n## Architecture Overview\n\nThe project follows the principles of **Clean Architecture** to ensure a separation of concerns.\n\n- **`src/scanner_lib` (Core Library - DLL):**\n  - **Domain (`domain.h`):** Contains the core data structures (`ScanResult`). It has no dependencies.\n  - **Application (`scanner.h`, `thread_pool.h`):** Contains the application-specific logic and orchestration (`IScanner`, `ThreadPool`). Depends only on the Domain.\n  - **Infrastructure (`csv_hash_database.h`, etc.):** Contains the concrete implementations of external-facing components. It implements interfaces defined in the Application layer.\n- **`src/scanner_cli` (Presentation Layer - EXE):**\n  - The command-line interface. It is the \"Composition Root\" that uses the library's public **Builder API** to assemble the application and present the results. It depends on the library but not on its internal details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregorykogan%2Ffile-scanner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgregorykogan%2Ffile-scanner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregorykogan%2Ffile-scanner/lists"}