{"id":13515240,"url":"https://github.com/blueconic/browscap-java","last_synced_at":"2026-01-24T23:16:39.890Z","repository":{"id":40744838,"uuid":"89475471","full_name":"blueconic/browscap-java","owner":"blueconic","description":"A blazingly fast and memory efficient (thread-safe) Java client on top of the BrowsCap CSV source files.","archived":false,"fork":false,"pushed_at":"2025-05-21T14:58:04.000Z","size":141471,"stargazers_count":203,"open_issues_count":1,"forks_count":40,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-07-24T01:47:54.743Z","etag":null,"topics":["browscap","useragent","useragentparser"],"latest_commit_sha":null,"homepage":"","language":"Java","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/blueconic.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.txt","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}},"created_at":"2017-04-26T11:55:37.000Z","updated_at":"2025-07-06T04:38:44.000Z","dependencies_parsed_at":"2024-06-17T12:13:36.703Z","dependency_job_id":"5972e46f-8600-4ccf-84ce-e896bb577ec0","html_url":"https://github.com/blueconic/browscap-java","commit_stats":null,"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"purl":"pkg:github/blueconic/browscap-java","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blueconic%2Fbrowscap-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blueconic%2Fbrowscap-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blueconic%2Fbrowscap-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blueconic%2Fbrowscap-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blueconic","download_url":"https://codeload.github.com/blueconic/browscap-java/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blueconic%2Fbrowscap-java/sbom","scorecard":{"id":244450,"data":{"date":"2025-08-11","repo":{"name":"github.com/blueconic/browscap-java","commit":"bb94fabdeae84d4e1e651c9f66e4c3706a24fb65"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:29","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/maven.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":1,"reason":"Found 4/23 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":2,"reason":"3 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/blueconic/browscap-java/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/blueconic/browscap-java/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/blueconic/browscap-java/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:70: update your workflow using https://app.stepsecurity.io/secureworkflow/blueconic/browscap-java/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/blueconic/browscap-java/maven.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/blueconic/browscap-java/maven.yml/master?enable=pin","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 1.5.1 not signed: https://api.github.com/repos/blueconic/browscap-java/releases/220101728","Warn: release artifact 1.5.0 not signed: https://api.github.com/repos/blueconic/browscap-java/releases/212153107","Warn: release artifact 1.4.5 not signed: https://api.github.com/repos/blueconic/browscap-java/releases/201357547","Warn: release artifact 1.4.4 not signed: https://api.github.com/repos/blueconic/browscap-java/releases/160821705","Warn: release artifact 1.4.3 not signed: https://api.github.com/repos/blueconic/browscap-java/releases/132662720","Warn: release artifact 1.5.1 does not have provenance: https://api.github.com/repos/blueconic/browscap-java/releases/220101728","Warn: release artifact 1.5.0 does not have provenance: https://api.github.com/repos/blueconic/browscap-java/releases/212153107","Warn: release artifact 1.4.5 does not have provenance: https://api.github.com/repos/blueconic/browscap-java/releases/201357547","Warn: release artifact 1.4.4 does not have provenance: https://api.github.com/repos/blueconic/browscap-java/releases/160821705","Warn: release artifact 1.4.3 does not have provenance: https://api.github.com/repos/blueconic/browscap-java/releases/132662720"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 4 commits out of 11 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T07:18:05.143Z","repository_id":40744838,"created_at":"2025-08-17T07:18:05.143Z","updated_at":"2025-08-17T07:18:05.143Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28738980,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T22:12:27.248Z","status":"ssl_error","status_checked_at":"2026-01-24T22:12:10.529Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["browscap","useragent","useragentparser"],"created_at":"2024-08-01T05:01:08.199Z","updated_at":"2026-01-24T23:16:39.846Z","avatar_url":"https://github.com/blueconic.png","language":"Java","readme":"[![Java CI with Maven](https://github.com/blueconic/browscap-java/actions/workflows/maven.yml/badge.svg)](https://github.com/blueconic/browscap-java/actions/workflows/maven.yml)\n[![Project Map](https://sourcespy.com/shield.svg)](https://sourcespy.com/github/blueconicbrowscapjava/)\n\n# browscap-java\nA blazingly fast and memory efficient (thread-safe) Java client on top of the BrowsCap [CSV source files](https://github.com/browscap/browscap).\nThe BrowsCap version currently shipped is: 6001008.\n\n## Description\nThis library can be used to parse useragent headers in order to extract information about the used browser, browser version, platform, platform version and device type. Very useful to determine if the client is a desktop, tablet or mobile device or to determine if the client is on Windows or Mac OS (just to name a few examples).\n\n## Algorithm\nWe got some questions on the how and why of our algorithm and why it is \"blazingly fast and efficient\".\nIn short, this is how our algorithm works:\n\n1. All CSV lines are read and parsed in our own data structures (e.g. \"Rule\" objects).\n-- This doesn't involve regular expressions (which are memory consuming and costly) but uses a smart way of doing substrings on the CSV expression.\n-- The results of the substring operations (startsWith, endsWith, findIndices in SearchableString) are cached, so subsequent calls are very fast.\n2. When all rules are generated, they're sorted by size and alphabet, so the first match can be returned immediately.\n3. When looking up a useragent, all rules are filtered based on the \"parts\" of an expression. Most rules can be easily discarded because they don't contain a specific substring.\n4. The filtering mechanism is based on bitset operations, which are very fast for large data sets.\n\n## Notes\n* Although this library is very fast, implementing a cache is advisable. Since cache strategies differ per usecase, this library doesn't ship with one out of the box.\n* All BrowsCap fields are available by configuration, but the following fields are loaded by default:\n  * browser (e.g. Chrome)\n  * browserType (e.g. Browser or Application)\n  * browserMajorVersion (e.g. 80 in case of Chrome)\n  * deviceType (e.g. Mobile Phone, Desktop, Tablet, Console, TV Device)\n  * platform (e.g. Android, iOS, Win7, Win8, Win10)\n  * platformVersion (e.g. 4.2, 10 depending on what the platform is)\n* The fields _are_ configurable by specifying a list of BrowsCapFields in the constructor of the UserAgentParser.\n* The CSV file is read in a streaming way, so it's processed line by line. This makes it more memory efficient than loading the whole into memory first.\n* 1000+ user agents are tested in the unit tests.\n* GraalVM Native Image is supported since 1.4.0\n\n## Sorting the CSV file\nThe BrowsCap source file is sorted when building via Maven, see `data-preprocessor.groovy`.\nWhen using your own source file, make sure to sort it as well to speed the startup performance.\n\n## Future\nPossible new features we're thinking of (and are not yet present):\n* Auto-update the BrowsCap CSV\n\n## Maven\nAdd this to the dependencies in your pom.xml.\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.blueconic\u003c/groupId\u003e\n  \u003cartifactId\u003ebrowscap-java\u003c/artifactId\u003e\n  \u003cversion\u003e1.5.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Usage\n```java\nimport com.blueconic.browscap.BrowsCapField;\nimport com.blueconic.browscap.Capabilities;\nimport com.blueconic.browscap.ParseException;\nimport com.blueconic.browscap.UserAgentParser;\nimport com.blueconic.browscap.UserAgentService;\n\n// ... class definition\n\n// create a parser with the default fields\nfinal UserAgentParser parser = new UserAgentService().loadParser(); // handle IOException and ParseException\n\n// or create a parser with a custom defined field list\n// the list of available fields can be seen inthe BrowsCapField enum\nfinal UserAgentParser parser =\n        new UserAgentService().loadParser(Arrays.asList(BrowsCapField.BROWSER, BrowsCapField.BROWSER_TYPE,\n                BrowsCapField.BROWSER_MAJOR_VERSION,\n                BrowsCapField.DEVICE_TYPE, BrowsCapField.PLATFORM, BrowsCapField.PLATFORM_VERSION,\n                BrowsCapField.RENDERING_ENGINE_VERSION, BrowsCapField.RENDERING_ENGINE_NAME,\n                BrowsCapField.PLATFORM_MAKER, BrowsCapField.RENDERING_ENGINE_MAKER));\n\n// It's also possible to supply your own ZIP file by supplying a correct path to a ZIP file in the constructor.\n// This can be used when a new BrowsCap version is released which is not yet bundled in this package.\n// final UserAgentParser parser = new UserAgentService(\"E:\\\\anil\\\\browscap.zip\").loadParser();\n\n// parser can be re-used for multiple lookup calls\nfinal String userAgent = \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36\";\nfinal Capabilities capabilities = parser.parse(userAgent);\n\n// the default fields have getters\nfinal String browser = capabilities.getBrowser();\nfinal String browserType = capabilities.getBrowserType();\nfinal String browserMajorVersion = capabilities.getBrowserMajorVersion();\nfinal String deviceType = capabilities.getDeviceType();\nfinal String platform = capabilities.getPlatform();\nfinal String platformVersion = capabilities.getPlatformVersion();\n\n// the custom defined fields are available\nfinal String renderingEngineMaker = capabilities.getValue(BrowsCapField.RENDERING_ENGINE_MAKER);\n\n// do something with the values\n\n```\n","funding_links":[],"categories":["Java"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblueconic%2Fbrowscap-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblueconic%2Fbrowscap-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblueconic%2Fbrowscap-java/lists"}