main 18a012001d4c cached
284 files
4.3 MB
1.1M tokens
1528 symbols
1 requests
Download .txt
Showing preview only (4,636K chars total). Download the full file or copy to clipboard to get everything.
Repository: bernardladenthin/BitcoinAddressFinder
Branch: main
Commit: 18a012001d4c
Files: 284
Total size: 4.3 MB

Directory structure:
gitextract_rp99wxvr/

├── .claude/
│   └── skills/
│       ├── java-tdd-guide/
│       │   └── SKILL.md
│       └── tdd/
│           └── SKILL.md
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── assembly.yml
│       ├── claude-code-review.yml
│       ├── claude.yml
│       ├── codeql.yml
│       ├── coverage.yml
│       └── matrixci.yml
├── .gitignore
├── .mvn/
│   └── jvm.config
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CODE_WRITING_GUIDE.md
├── LICENSE
├── README.md
├── TEST_WRITING_GUIDE.md
├── build.bat
├── examples/
│   ├── addresses/
│   │   ├── fileContainingAddresses0.txt
│   │   ├── fileContainingAddresses1.tsv
│   │   └── fileContainingAddresses2.csv
│   ├── config_AddressFilesToLMDB.json
│   ├── config_Find_1OpenCLDevice.json
│   ├── config_Find_1OpenCLDeviceAnd2CPUProducer.json
│   ├── config_Find_8CPUProducer.json
│   ├── config_Find_SecretsFile.json
│   ├── config_LMDBToAddressFile.json
│   ├── config_OpenCLInfo.json
│   ├── logbackConfiguration.xml
│   ├── run_AddressFilesToLMDB.bat
│   ├── run_Find_1OpenCLDevice.bat
│   ├── run_Find_1OpenCLDeviceAnd2CPUProducer.bat
│   ├── run_Find_8CPUProducer.bat
│   ├── run_Find_SecretsFile.bat
│   ├── run_LMDBToAddressFile.bat
│   ├── run_OpenCLInfo.bat
│   ├── secrets/
│   │   ├── fileContainingSecrets_BIG_INTEGER.txt
│   │   ├── fileContainingSecrets_DUMPED_RIVATE_KEY.txt
│   │   ├── fileContainingSecrets_SHA256.txt
│   │   └── fileContainingSecrets_STRING_DO_SHA256.txt
│   └── websocket.html
├── helper/
│   ├── bitinfocharts_com_scraping/
│   │   ├── scraping.py
│   │   └── start.bat
│   └── dumpwallet/
│       └── dumpwallet.py
├── pom.xml
├── skills/
│   └── tdd.md
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── net/
│   │   │       └── ladenthin/
│   │   │           └── bitcoinaddressfinder/
│   │   │               ├── AbstractPlaintextFile.java
│   │   │               ├── AbstractProducer.java
│   │   │               ├── AddressFile.java
│   │   │               ├── AddressFilesToLMDB.java
│   │   │               ├── AddressFormatNotAcceptedException.java
│   │   │               ├── AddressToCoin.java
│   │   │               ├── AddressTxtLine.java
│   │   │               ├── AddressType.java
│   │   │               ├── BIP39KeyProducer.java
│   │   │               ├── BIP39Wordlist.java
│   │   │               ├── Base36Decoder.java
│   │   │               ├── Bech32Helper.java
│   │   │               ├── BitHelper.java
│   │   │               ├── ByteBufferUtility.java
│   │   │               ├── ByteConversion.java
│   │   │               ├── Consumer.java
│   │   │               ├── ConsumerJava.java
│   │   │               ├── EndiannessConverter.java
│   │   │               ├── FileHelper.java
│   │   │               ├── Finder.java
│   │   │               ├── Interruptable.java
│   │   │               ├── KeyUtility.java
│   │   │               ├── LMDBToAddressFile.java
│   │   │               ├── NetworkParameterFactory.java
│   │   │               ├── OpenCLContext.java
│   │   │               ├── OpenCLGridResult.java
│   │   │               ├── OpenClTask.java
│   │   │               ├── PrivateKeyTooLargeException.java
│   │   │               ├── PrivateKeyValidator.java
│   │   │               ├── Producer.java
│   │   │               ├── ProducerJava.java
│   │   │               ├── ProducerJavaSecretsFiles.java
│   │   │               ├── ProducerOpenCL.java
│   │   │               ├── ProducerState.java
│   │   │               ├── ProducerStateProvider.java
│   │   │               ├── PublicKeyBytes.java
│   │   │               ├── RandomSecretSupplier.java
│   │   │               ├── ReadStatistic.java
│   │   │               ├── ReleaseCLObject.java
│   │   │               ├── SecretSupplier.java
│   │   │               ├── SecretsFile.java
│   │   │               ├── SeparatorFormat.java
│   │   │               ├── Shutdown.java
│   │   │               ├── Statistics.java
│   │   │               ├── cli/
│   │   │               │   └── Main.java
│   │   │               ├── configuration/
│   │   │               │   ├── CAddressFileOutputFormat.java
│   │   │               │   ├── CAddressFilesToLMDB.java
│   │   │               │   ├── CCommand.java
│   │   │               │   ├── CConfiguration.java
│   │   │               │   ├── CConsumerJava.java
│   │   │               │   ├── CFinder.java
│   │   │               │   ├── CKeyProducerJava.java
│   │   │               │   ├── CKeyProducerJavaBip39.java
│   │   │               │   ├── CKeyProducerJavaIncremental.java
│   │   │               │   ├── CKeyProducerJavaRandom.java
│   │   │               │   ├── CKeyProducerJavaRandomInstance.java
│   │   │               │   ├── CKeyProducerJavaReceiver.java
│   │   │               │   ├── CKeyProducerJavaSocket.java
│   │   │               │   ├── CKeyProducerJavaWebSocket.java
│   │   │               │   ├── CKeyProducerJavaZmq.java
│   │   │               │   ├── CLMDBConfigurationReadOnly.java
│   │   │               │   ├── CLMDBConfigurationWrite.java
│   │   │               │   ├── CLMDBToAddressFile.java
│   │   │               │   ├── CProducer.java
│   │   │               │   ├── CProducerJava.java
│   │   │               │   ├── CProducerJavaSecretsFiles.java
│   │   │               │   ├── CProducerOpenCL.java
│   │   │               │   ├── CSecretFormat.java
│   │   │               │   └── UnknownSecretFormatException.java
│   │   │               ├── eckey/
│   │   │               │   └── Secp256k1.java
│   │   │               ├── keyproducer/
│   │   │               │   ├── AbstractKeyProducer.java
│   │   │               │   ├── AbstractKeyProducerQueueBuffered.java
│   │   │               │   ├── ConnectionUtils.java
│   │   │               │   ├── KeyProducer.java
│   │   │               │   ├── KeyProducerIdIsNotUniqueException.java
│   │   │               │   ├── KeyProducerIdNullException.java
│   │   │               │   ├── KeyProducerIdUnknownException.java
│   │   │               │   ├── KeyProducerJava.java
│   │   │               │   ├── KeyProducerJavaBip39.java
│   │   │               │   ├── KeyProducerJavaIncremental.java
│   │   │               │   ├── KeyProducerJavaRandom.java
│   │   │               │   ├── KeyProducerJavaSocket.java
│   │   │               │   ├── KeyProducerJavaWebSocket.java
│   │   │               │   ├── KeyProducerJavaZmq.java
│   │   │               │   └── NoMoreSecretsAvailableException.java
│   │   │               ├── opencl/
│   │   │               │   ├── OpenCLBuilder.java
│   │   │               │   ├── OpenCLDevice.java
│   │   │               │   ├── OpenCLDeviceSelection.java
│   │   │               │   ├── OpenCLPlatform.java
│   │   │               │   └── OpenCLPlatformSelector.java
│   │   │               └── persistence/
│   │   │                   ├── Persistence.java
│   │   │                   ├── PersistenceUtils.java
│   │   │                   └── lmdb/
│   │   │                       └── LMDBPersistence.java
│   │   └── resources/
│   │       ├── copyfromhashcat/
│   │       │   ├── inc_common.cl
│   │       │   ├── inc_common.h
│   │       │   ├── inc_ecc_secp256k1.cl
│   │       │   ├── inc_ecc_secp256k1.h
│   │       │   ├── inc_hash_ripemd160.cl
│   │       │   ├── inc_hash_ripemd160.h
│   │       │   ├── inc_hash_sha256.cl
│   │       │   ├── inc_hash_sha256.h
│   │       │   ├── inc_platform.cl
│   │       │   ├── inc_platform.h
│   │       │   ├── inc_types.h
│   │       │   └── inc_vendor.h
│   │       ├── inc_defines.h
│   │       ├── inc_ecc_secp256k1custom.cl
│   │       ├── mnemonic/
│   │       │   └── wordlist/
│   │       │       ├── chinese_simplified.txt
│   │       │       ├── chinese_traditional.txt
│   │       │       ├── czech.txt
│   │       │       ├── english.txt
│   │       │       ├── french.txt
│   │       │       ├── italian.txt
│   │       │       ├── japanese.txt
│   │       │       ├── korean.txt
│   │       │       ├── portuguese.txt
│   │       │       ├── russian.txt
│   │       │       ├── spanish.txt
│   │       │       └── turkish.txt
│   │       ├── simplelogger.properties
│   │       └── unused/
│   │           ├── calc_addrs.cl
│   │           ├── calc_addrs_fix_zero.cl
│   │           └── gpu.cl
│   └── test/
│       ├── java/
│       │   └── net/
│       │       └── ladenthin/
│       │           └── bitcoinaddressfinder/
│       │               ├── AbstractPlaintextFileTest.java
│       │               ├── AbstractProducerTest.java
│       │               ├── AbstractProducerTestImpl.java
│       │               ├── AddressFileTest.java
│       │               ├── AddressFilesToLMDBTest.java
│       │               ├── AddressFormatNotAcceptedExceptionTest.java
│       │               ├── AddressToCoinTest.java
│       │               ├── AddressTxtLineTest.java
│       │               ├── AddressTypeTest.java
│       │               ├── AwaitTimeTest.java
│       │               ├── AwaitTimeTests.java
│       │               ├── BIP39DataProvider.java
│       │               ├── BIP39KeyProducerTest.java
│       │               ├── BIP39WordlistTest.java
│       │               ├── Base36DecoderTest.java
│       │               ├── Bech32HelperTest.java
│       │               ├── BitHelperTest.java
│       │               ├── ByteBufferUtilityTest.java
│       │               ├── ByteConversionTest.java
│       │               ├── CommonDataProvider.java
│       │               ├── ConsumerJavaTest.java
│       │               ├── EndiannessConverterTest.java
│       │               ├── EqualHashCodeToStringTestHelper.java
│       │               ├── FileHelperTest.java
│       │               ├── FinderTest.java
│       │               ├── HexEncodeTest.java
│       │               ├── KeyUtilityTest.java
│       │               ├── LMDBBase.java
│       │               ├── LMDBPersistencePerformanceTest.java
│       │               ├── LMDBPersistenceTest.java
│       │               ├── LMDBPlatformAssume.java
│       │               ├── LMDBToAddressFileTest.java
│       │               ├── LogLevelChange.java
│       │               ├── MainTest.java
│       │               ├── ManualDebugConstants.java
│       │               ├── MockConsumer.java
│       │               ├── MockKeyProducer.java
│       │               ├── MockKeyProducerTest.java
│       │               ├── NetworkParameterFactoryTest.java
│       │               ├── OpenCLBuilderTest.java
│       │               ├── OpenCLContextTest.java
│       │               ├── OpenCLDeviceTest.java
│       │               ├── OpenCLGridResultTest.java
│       │               ├── OpenCLPlatformAssume.java
│       │               ├── OpenCLPlatformSelectorTest.java
│       │               ├── OpenCLPlatformTest.java
│       │               ├── OpenCLTest.java
│       │               ├── PlatformAssume.java
│       │               ├── PrivateKeyTooLargeExceptionTest.java
│       │               ├── PrivateKeyValidatorTest.java
│       │               ├── ProbeAddressesOpenCLTest.java
│       │               ├── ProducerJavaSecretsFilesTest.java
│       │               ├── ProducerJavaTest.java
│       │               ├── ProducerOpenCLTest.java
│       │               ├── ProducerStateTest.java
│       │               ├── PublicKeyBytesTest.java
│       │               ├── RandomSecretSupplierTest.java
│       │               ├── ReadStatisticTest.java
│       │               ├── SecretsFileTest.java
│       │               ├── SeparatorFormatTest.java
│       │               ├── StatisticsTest.java
│       │               ├── ToStringTest.java
│       │               ├── configuration/
│       │               │   ├── CKeyProducerJavaIncrementalTest.java
│       │               │   ├── CProducerTest.java
│       │               │   └── UnknownSecretFormatExceptionTest.java
│       │               ├── eckey/
│       │               │   └── Secp256k1Test.java
│       │               ├── keyproducer/
│       │               │   ├── AbstractKeyProducerQueueBufferedTest.java
│       │               │   ├── ConnectionUtilsTest.java
│       │               │   ├── KeyProducerIdIsNotUniqueExceptionTest.java
│       │               │   ├── KeyProducerIdNullExceptionTest.java
│       │               │   ├── KeyProducerIdUnknownExceptionTest.java
│       │               │   ├── KeyProducerJavaBip39Test.java
│       │               │   ├── KeyProducerJavaIncrementalTest.java
│       │               │   ├── KeyProducerJavaRandomTest.java
│       │               │   ├── KeyProducerJavaSocketTest.java
│       │               │   ├── KeyProducerJavaTest.java
│       │               │   ├── KeyProducerJavaWebSocketTest.java
│       │               │   ├── KeyProducerJavaZmqTest.java
│       │               │   ├── KeyProducerTestUtility.java
│       │               │   ├── NoMoreSecretsAvailableExceptionTest.java
│       │               │   └── TestTimeProvider.java
│       │               ├── persistence/
│       │               │   └── PersistenceUtilsTest.java
│       │               └── staticaddresses/
│       │                   ├── AbstractTestAddresses.java
│       │                   ├── AddressesFileSpecialUsecases.java
│       │                   ├── AddressesFiles.java
│       │                   ├── StaticAddressesFiles.java
│       │                   ├── StaticKey.java
│       │                   ├── TestAddresses.java
│       │                   ├── TestAddresses1337.java
│       │                   ├── TestAddresses42.java
│       │                   ├── TestAddressesFiles.java
│       │                   ├── TestAddressesLMDB.java
│       │                   └── enums/
│       │                       ├── P2PKH.java
│       │                       ├── P2SH.java
│       │                       ├── P2WPKH.java
│       │                       ├── PublicAddress.java
│       │                       └── StaticUnsupportedAddress.java
│       └── resources/
│           ├── testOpenCLInfo/
│           │   ├── config_OpenCLInfo.js
│           │   ├── config_OpenCLInfo.json
│           │   ├── config_OpenCLInfo.yaml
│           │   └── config_OpenCLInfo.yml
│           ├── testRoundtrip/
│           │   ├── addresses/
│           │   │   ├── fileContainingAddresses0.txt
│           │   │   ├── fileContainingAddresses1.tsv
│           │   │   └── fileContainingAddresses2.csv
│           │   ├── config_AddressFilesToLMDB.json
│           │   ├── config_Find_1OpenCLDevice.json
│           │   ├── config_Find_SecretsFile.json
│           │   ├── config_LMDBToAddressFile.json
│           │   └── secrets/
│           │       ├── fileContainingSecrets_BIG_INTEGER.txt
│           │       ├── fileContainingSecrets_DUMPED_RIVATE_KEY.txt
│           │       ├── fileContainingSecrets_SHA256.txt
│           │       └── fileContainingSecrets_STRING_DO_SHA256.txt
│           └── vectors.json
├── testAddressTxtLineTest.bat
└── update.bat

================================================
FILE CONTENTS
================================================

================================================
FILE: .claude/skills/java-tdd-guide/SKILL.md
================================================
---
name: java-tdd-guide
description: Bernard Ladenthin's personal Java Test-Driven Development skill — version 1.0.0 — Red → Green → Refactor workflow with project-independent conventions
---

# Java TDD Skill — Test-Driven Development

**Author:** Bernard Ladenthin  
**Version:** 1.0.0  
**License:** Apache 2.0  

This is a personal, reusable Java TDD guide for use across multiple projects. All examples are generic and project-independent. Project-specific patterns and constants are documented separately in each project's CLAUDE.md.

---

## TDD Workflow — Red → Green → Refactor

Follow the **Red → Green → Refactor** cycle rigorously. Every new behaviour must be covered by a failing test *before* the production code is written.

### 1 — Red (failing test first)
Write one test that precisely describes the next desired behaviour. The test must compile but **must fail** when run. Do not write any production code yet.

### 2 — Green (minimum production code)
Write the smallest change to production code that makes the failing test pass. Do not add code that is not driven by a test.

### 3 — Refactor
Improve the implementation and the test code without changing observable behaviour. All tests must stay green.

Repeat for each behaviour increment.

---

## Test File Structure

### File Header — Apache 2.0 License

Every test file **must** start with the formatter-off block enclosing the Apache 2.0 license header:

```java
// @formatter:off
/**
 * Copyright <YEAR> <Author> <email>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// @formatter:on
package com.example.foo;
```

- The `// @formatter:off` / `// @formatter:on` pair wraps **only** the license block.
- The year must match the file creation year (not the current year).

---

## Test Framework Stack

| Concern | Mandatory choice |
|---|---|
| Runner | JUnit 4 (`@Test`, `@Before`, `@Rule`) |
| Parameterized | `@RunWith(DataProviderRunner.class)` + `@UseDataProvider` (only when the class has at least one `@UseDataProvider` method) |
| Assertions | Hamcrest only — `assertThat(actual, is(equalTo(expected)))` |
| Mocking | Mockito — `mock()`, `when()`, `verify()`, `ArgumentCaptor` |
| Temp files | `@Rule public TemporaryFolder folder = new TemporaryFolder()` |

**Never use:**
- `assertEquals`, `assertTrue`, `assertFalse`, `assertNotNull` from `org.junit.Assert`
- TestNG or JUnit 5

---

## Class Layout

```java
@RunWith(DataProviderRunner.class)   // only when @UseDataProvider is present
public class FooTest {

    // shared, constructed-once immutable fields
    private final Bar bar = new Bar();
    private final BazHelper helper = new BazHelper();

    // mocks that must be fresh per test — declare field here, initialize in @Before
    private Logger mockLogger;

    @Before
    public void setUp() {
        mockLogger = mock(Logger.class);
    }
    // Omit @Before entirely when it does no meaningful work.
```

Omit `@RunWith` if no data providers are used. Omit empty `@Before` methods.

---

## Test Method Naming

Pattern: **`methodUnderTest_inputOrCondition_expectedBehavior`**

```
foo_emptyInput_returnsNull
bar_validArgumentsGiven_returnsExpected
baz_negativeValue_throwsException
interrupt_queueNotEmpty_waitedForDuration
toString_whenCalled_containsClassNameAndIdentityHash
```

**Rules:**
- All three segments are **required**, separated by underscores.
- Use camelCase within each segment.
- Exception tests end with `_throwsException` or `_exceptionThrown`.
- No-op/smoke tests: `_noExceptionThrown`.
- `toString` tests: describe exact content (identity hash or structured format).
- Logging assertions: include `_logged` or `_logsError`.

---

## Test Body — AAA Structure

Every test body **must** follow Arrange / Act / Assert with explicit section comments:

```java
@Test
public void methodName_conditionGiven_expectedResult() {
    // arrange
    Foo sut = new Foo(42);

    // act
    String result = sut.bar();

    // assert
    assertThat(result, is(equalTo("expected")));
}
```

### `// pre-assert` — two valid positions

**1. Before `// act`** — assert a precondition or input invariant:

```java
// arrange
String input = "test-value";

// pre-assert
assertThat(input, not(emptyString()));

// act
String result = sut.process(input);

// assert
assertThat(result, is(equalTo("expected")));
```

**2. Between `// act` and `// assert`** — null-guard before accessing result fields:

```java
// act
FooResult result = sut.compute();

// pre-assert
assertThat(result, is(notNullValue()));

// assert
assertThat(result.getValue(), is(equalTo(expected)));
```

**Rules:**
- Do **not** use `Objects.requireNonNull(...)` in tests; use `// pre-assert` with `assertThat(x, is(notNullValue()))` instead.
- The `// arrange` section may be omitted only when there is genuinely nothing to arrange.
- Keep the act to a **single method call** whenever possible.

---

## Editor Folds — Mandatory Grouping

Tests within a class **must** be grouped using editor fold regions, one fold per method/feature under test:

```java
// <editor-fold defaultstate="collapsed" desc="methodName">
@Test
public void methodName_caseA_resultA() { ... }

@Test
public void methodName_caseB_resultB() { ... }
// </editor-fold>
```

**Rules:**
- The `desc` attribute equals the method name (or a short feature label).
- `defaultstate="collapsed"` is **mandatory** on every fold.
- All tests for the same method go inside a single fold.
- Tests for different methods **must** be in different folds.
- Order folds logically (simple cases first, edge cases and exceptions last).

---

## Assertions — Hamcrest Style

All assertions use Hamcrest `assertThat`:

```java
// equality
assertThat(result, is(equalTo(expected)));

// null / not null
assertThat(result, is(nullValue()));
assertThat(result, is(notNullValue()));

// boolean
assertThat(flag, is(true));
assertThat(flag, is(false));

// negation
assertThat(result, is(not(equalTo(unexpected))));

// strings
assertThat(message, containsString("substring"));
assertThat(message, matchesPattern("Regex\\d+"));
assertThat(output, not(emptyOrNullString()));

// collections
assertThat(list, hasSize(3));
assertThat(list, is(empty()));
assertThat(list, hasItems("a", "b"));

// numbers / comparable
assertThat(index, is(lessThan(colonIndex)));
assertThat(waitTime, is(greaterThan(minExpected)));

// type
assertThat(obj, instanceOf(Foo.class));
```

**Imports:**
```java
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;   // when many matchers are used
// or specific imports when only a few are needed
```

---

## Exception Testing

### Pattern A — Simple (no message check)

```java
@Test(expected = IllegalArgumentException.class)
public void foo_nullInput_throwsException() {
    // act
    sut.foo(null);
}
```

### Pattern B — With message verification (try/catch/fail)

```java
@Test
public void foo_invalidInput_throwsException() {
    try {
        // act
        sut.foo("invalid");
        fail("Expected IllegalArgumentException");
    } catch (IllegalArgumentException e) {
        // assert
        assertThat(e.getMessage(), containsString("expected error text"));
    }
}
```

Import for `fail()`:
```java
import static org.junit.Assert.fail;
```

---

## Data Providers (Parameterized Tests)

### Centralized Pattern

All data providers belong in a centralized `CommonDataProvider` class. Each provider follows this pattern:

```java
// 1. Constant for the provider name
public final static String DATA_PROVIDER_MY_CASES = "myCases";

// 2. Javadoc linking to which test it serves
/** For {@link FooTest}. */
@DataProvider
public static Object[][] myCases() {
    return new Object[][] {
        { inputA, expectedA },
        { inputB, expectedB },
    };
}
```

### Consuming a data provider

```java
@RunWith(DataProviderRunner.class)
public class FooTest {

    @Test
    @UseDataProvider(value = CommonDataProvider.DATA_PROVIDER_MY_CASES, location = CommonDataProvider.class)
    public void foo_inputGiven_returnsExpected(String input, String expected) {
        // arrange
        Foo sut = new Foo();

        // act
        String result = sut.bar(input);

        // assert
        assertThat(result, is(equalTo(expected)));
    }
}
```

### Enum-based providers

```java
@DataProvider
public static Object[][] allEnumValues() {
    return transformFlatToObjectArrayArray(MyEnum.values());
}
```

### Cartesian product providers

```java
@DataProvider
public static Object[][] typeAndSize() {
    return mergeMany(types(), sizes());
}
```

---

## Named Constants — DRY, No Magic Literals

Every semantic value must be a named `public static final` or `private static final` constant with Javadoc.

**Rules:**
- Every string, number, or flag literal that carries meaning **must** be a named constant.
- Constants belong at the class level, before constructors and methods.
- Name constants by their **meaning or role**, not the raw value.
- Each constant must have **Javadoc** explaining what it represents and why.
- Derived values must be computed from source constants, never duplicated.
- Radix values (`16`, `10`, `2`) should be referenced through helper constants, never as bare integers.

**Bad:**
```java
return new BigInteger("FFFFFFFFFFFFFFFF", 16);
if (batchSize > 256) { ... }
```

**Good:**
```java
/**
 * The maximum valid size for batch processing.
 * Chosen based on performance testing with typical workloads.
 */
public static final int MAX_BATCH_SIZE = 256;

/**
 * The hex value for all 64 bits set.
 * Derived from {@link #MAX_BATCH_SIZE} — do not duplicate the literal.
 */
public static final String MAX_VALUE_HEX = "FF".repeat(8);

if (batchSize > MAX_BATCH_SIZE) { ... }
```

---

## Logger Injection — Constructor Over Setter

When a class uses an SLF4J `Logger` and tests need to inject a mock logger, prefer **constructor-based injection**.

**Pattern — two constructors:**

```java
public class MyService {
    private final Logger logger;

    // Production constructor — creates its own logger
    public MyService(Config config) {
        this(config, LoggerFactory.getLogger(MyService.class));
    }

    // Test constructor — accepts an injected logger
    @VisibleForTesting
    MyService(Config config, Logger logger) {
        this.config = config;
        this.logger = logger;
    }
}
```

**Rules:**
- The `logger` field should be `private final`.
- The production constructor delegates to the test constructor (or vice versa) — never duplicate initialization.
- The `@VisibleForTesting` constructor has package-private visibility.
- A `setLogger` method is a last resort — only if constructor injection is infeasible.

**Test usage:**
```java
Logger mockLogger = mock(Logger.class);
MyService service = new MyService(config, mockLogger);
```

---

## Null Safety — JSpecify Annotations

Use **JSpecify** `@Nullable` annotation for optional values; `@NonNull` is the default (no annotation needed).

```java
import org.jspecify.annotations.Nullable;

public @Nullable String getOptional() { return null; }

// Array null annotations — place between type and brackets
private byte @Nullable [] buffer;           // array itself may be null
public byte @NonNull [] getBuffer() { }     // array is guaranteed non-null
```

**Compiler enforcement:**
A static checker (e.g., NullAway) enforces null safety at compile time. Missing `@Nullable` on a nullable return or field causes a **compilation failure**.

---

## @VisibleForTesting Annotation

Mark package-private or protected members that are only exposed for testing:

```java
@VisibleForTesting
static Duration AWAIT_DURATION = Duration.ofSeconds(20);

@VisibleForTesting
final ExecutorService executor = Executors.newFixedThreadPool(4);
```

Tests may modify `@VisibleForTesting` static fields to shorten wait times or adjust test-specific behaviour.

---

## Mocking & Logger Verification

### Capturing and asserting log output

```java
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(logger, times(1)).info(captor.capture());
List<String> arguments = captor.getAllValues();
assertThat(arguments.get(0), is(equalTo("Initialized.")));
```

### Verifying no interaction

```java
verify(logger, never()).error(anyString());
```

### Verifying with argument matchers

```java
verify(logger).error(contains("expectedSubstring"));
verify(mockLogger, times(1)).info(eq("Message"), eq(expectedValue));
```

**Imports:**
```java
import static org.mockito.Mockito.*;
import static org.mockito.ArgumentMatchers.*;
```

---

## Randomness — Always Fixed Seeds

All `Random` instances in tests **must** use a fixed seed:

```java
private final Random random = new Random(1337);
```

Never use `new Random()` (unseeded). Document the seed's significance when it matters:

```java
/** This random produces bits: 1, 0, 1, 0 — useful for testing boundary cases. */
private final Random random = new Random(1);
```

---

## TemporaryFolder / File System Tests

Use `TemporaryFolder` for tests that create files and directories:

```java
@Rule
public TemporaryFolder folder = new TemporaryFolder();

@Test
public void testFileHandling() throws IOException {
    // arrange
    File tempFile = folder.newFile("data.txt");
    File subdir = folder.newFolder("output");
    
    // use Files NIO for writing
    Files.writeString(tempFile.toPath(), "content");
    
    // act / assert
    // ...
}
```

**Rules:**
- Always use `folder.newFile(...)` and `folder.newFolder(...)` — never create manually.
- Cleanup is automatic when the test completes.

---

## Records & Immutability

Use Java `record` for immutable value objects:

```java
public record MyValue(@NonNull String name, int count) {
    // compact constructor for validation
    public MyValue {
        Objects.requireNonNull(name);
    }
}
```

**Rules:**
- `Objects.requireNonNull()` is **valid in production code** (not in tests).
- Mark immutable classes with `@Immutable` annotation when appropriate.
- For records containing mutable third-party types, suppress the Error Prone warning:

```java
@Immutable
public record Container(
    @SuppressWarnings("Immutable") MutableObject obj,
    @NonNull String name
) { }
```

---

## Concurrency Conventions

```java
// Thread-safe counters
private final AtomicLong hits = new AtomicLong();
private final AtomicInteger stateCounter = new AtomicInteger();

// Work queue
private final LinkedBlockingQueue<byte[]> workQueue;

// Thread pool — never raw Thread
private final ExecutorService executor = Executors.newFixedThreadPool(4);

// Shutdown synchronisation
private final CountDownLatch shutdownLatch = new CountDownLatch(1);
```

### Async/Concurrent Tests

Use `CountDownLatch` + `ExecutorService` + `Future` for coordinating async tests:

```java
@Test
public void asyncOperation_serverSendsData_clientReceives() throws Exception {
    // arrange
    int port = findFreePort();
    ExecutorService executorService = Executors.newCachedThreadPool();
    CountDownLatch serverStarted = new CountDownLatch(1);

    Future<Void> serverFuture = executorService.submit(() -> {
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            serverStarted.countDown();                // signal ready
            try (Socket client = serverSocket.accept();
                 DataOutputStream out = new DataOutputStream(client.getOutputStream())) {
                out.write(data);
            }
        }
        return null;
    });

    serverStarted.await();                            // wait for server to be ready

    // act
    String result = connectAndFetch(port);

    // assert
    assertThat(result, is(equalTo(expected)));

    serverFuture.get(5, TimeUnit.SECONDS);            // ensure server completed cleanly
    executorService.shutdown();
}

private static int findFreePort() throws IOException {
    try (ServerSocket s = new ServerSocket(0)) {
        return s.getLocalPort();
    }
}
```

---

## Equals / HashCode / ToString Contract Tests

Use a generic contract test helper with four instances (two for value A, two for value B):

```java
// arrange
Foo a1 = new Foo(valueA);
Foo a2 = new Foo(valueA);  // same data, different reference
Foo b1 = new Foo(valueB);
Foo b2 = new Foo(valueB);

// assert — A != B
EqualHashCodeToStringTestHelper helper = new EqualHashCodeToStringTestHelper(a1, a2, b1, b2);
helper.assertEqualsHashCodeToStringAIsDifferentToB();

// OR — A == B (same semantic content)
helper.assertEqualsHashCodeToStringAIsEqualToB();
```

For `toString()` tests verifying default object identity format:
```java
assertThat(output, matchesPattern("ClassName@\\p{XDigit}+"));
```

For `toString()` tests verifying structured content:
```java
assertThat(output, is(equalTo("Foo{name=bar, count=42}")));
```

---

## Import Style

Group imports in this order (no blank lines within groups, blank line between groups):

1. Standard Java (`java.*`, `javax.*`)
2. Third-party libraries (alphabetical)
3. Project classes (`com.example.*`)
4. Static imports (last, alphabetical)

```java
import java.io.IOException;
import java.util.List;

import org.junit.Test;
import org.mockito.Mock;

import com.example.foo.Foo;
import com.example.foo.Bar;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
```

Prefer **specific static imports** over wildcard when used 1–2 times. Use wildcard for Hamcrest matchers when many are used:
```java
import static org.hamcrest.Matchers.*;
```

---

## Array & Collection Assertions

### Do NOT use for-loops in assertions

**Problem:** For-loop iteration in assertions reduces readability.

```java
// ❌ BAD — uses for-loop
for (int i = 0; i < expected.length; i++) {
    assertThat(result[i], is(equalTo(expected[i])));
}
```

**Solution:** Compare entire arrays directly.

```java
// ✅ GOOD — compare whole array
assertThat(result, is(expected));
```

### Exception: iterating over all enum values is allowed

When verifying behaviour for **every value of an enum**, iterating via `EnumType.values()` is preferred. It ensures new enum constants are automatically covered:

```java
@Test
public void process_allEnumValues_succeeds() {
    for (MyEnum value : MyEnum.values()) {
        String result = sut.process(value);
        assertThat(result, not(emptyString()));
    }
}
```

### Pattern for zero-padded arrays

```java
@Test
public void decode_shorterInput_leftPaddedWithZeros() {
    // arrange
    byte[] original = {0x01, 0x02, 0x03};
    final int targetLength = 20;
    final int paddingLength = targetLength - original.length;
    byte[] expectedPadding = new byte[paddingLength];

    // act
    byte[] result = decoder.decode(original, targetLength);

    // assert
    assertThat(Arrays.copyOfRange(result, 0, paddingLength), is(expectedPadding));
    assertThat(Arrays.copyOfRange(result, paddingLength, targetLength), is(original));
}
```

---

## Constants Within a Fold (DRY)

When the same literal appears in **two or more tests in the same fold**, extract it as a `private static final` constant:

```java
// ✅ GOOD — one definition, both variants derived from it
private static final String CUSTOM_HEX = "FF";

sut.value = CUSTOM_HEX.toUpperCase();  // "FF"
sut.value = CUSTOM_HEX.toLowerCase();  // "ff"
assertThat(result, is(equalTo(new BigInteger(CUSTOM_HEX, 16))));
```

```java
// ❌ BAD — same literal repeated
sut.value = "FF";
sut.value = "ff";
assertThat(result, is(equalTo(BigInteger.valueOf(255))));
```

**Rule:** Constants belong to their fold. Do **not** share a constant between different folds even when values coincide — tests for different methods should remain logically independent.

---

## Preserving Existing Comments

When modifying existing test code (fixing bugs, applying guide compliance):

- **Keep all existing inline comments** that are correct and descriptive.
- **Only remove a comment** if it is factually wrong, misleading, or describes deleted code.
- **Add new comments** where added code is not self-explanatory.

Example — correct preservation:
```java
// arrange
String address = createAddress();

// Server socket binds        ← existing comment preserved
ServerSocket socket = new ServerSocket(port);

// act
String result = sut.process(address);

// assert
assertThat(result, not(emptyString()));
```

**Goal:** Minimize the diff to only lines that actually need changing.

---

## Anti-Patterns — What NOT To Do

| Anti-pattern | Correct alternative |
|---|---|
| `assertEquals(expected, actual)` | `assertThat(actual, is(equalTo(expected)))` |
| `assertTrue(condition)` | `assertThat(condition, is(true))` |
| `Assert.assertNotNull(x)` | `assertThat(x, is(notNullValue()))` |
| `Objects.requireNonNull(x)` as guard in test | `// pre-assert` with `assertThat(x, is(notNullValue()))` |
| Unseeded `new Random()` | `new Random(fixedSeed)` |
| Hard-coded address/constant strings | Use project-specific static constants |
| Missing `// arrange / act / assert` | Add the section comments always |
| Missing editor fold | Wrap each method group in `<editor-fold>` |
| Non-conforming test name like `testme()` | Rename to `methodName_condition_expectation()` |
| Empty `@Before` method | Remove it entirely |
| `@RunWith(DataProviderRunner.class)` without `@UseDataProvider` | Remove the `@RunWith` |
| For-loop iteration in assertions | Compare entire array at once — **exception:** `for (MyEnum v : MyEnum.values())` is allowed |
| Magic numbers like `result[9]` | Use `final int` constants: `result[targetLength - 1]` |
| Removing existing correct comments during fixes | Preserve comments; only remove factually wrong ones |

---

## Test Anatomy — Complete Reference Example

```java
// @formatter:off
/**
 * Copyright 2025 Your Name your.name@example.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// @formatter:on
package com.example.foo;

import java.io.IOException;
import java.util.List;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;

import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

@RunWith(DataProviderRunner.class)
public class FooTest {

    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    private Bar bar;

    @Before
    public void setUp() {
        bar = new Bar();
    }

    // <editor-fold defaultstate="collapsed" desc="someMethod">
    @Test
    public void someMethod_validInputGiven_returnsExpectedResult() {
        // arrange
        Foo sut = new Foo();

        // act
        String result = sut.someMethod("validInput");

        // assert
        assertThat(result, is(equalTo("expectedResult")));
    }

    @Test(expected = IllegalArgumentException.class)
    public void someMethod_nullGiven_throwsException() {
        // arrange
        Foo sut = new Foo();

        // act
        sut.someMethod(null);
    }

    @Test
    @UseDataProvider(value = CommonDataProvider.DATA_PROVIDER_MY_CASES, location = CommonDataProvider.class)
    public void someMethod_parameterizedInput_returnsExpected(String input, String expected) {
        // arrange
        Foo sut = new Foo();

        // act
        String result = sut.someMethod(input);

        // assert
        assertThat(result, is(equalTo(expected)));
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="toString">
    @Test
    public void toString_whenCalled_containsClassNameAndIdentityHash() {
        // arrange
        Foo sut = new Foo();

        // act
        String output = sut.toString();

        // assert
        assertThat(output, not(emptyOrNullString()));
        assertThat(output, matchesPattern("Foo@\\p{XDigit}+"));
    }
    // </editor-fold>
}
```

---

## Completeness Checklist

Before submitting code:

- [ ] At least one test was written and failed **before** the production code was written.
- [ ] Every production behaviour is covered by at least one test.
- [ ] All tests pass: `./mvnw test` (or equivalent for your project).
- [ ] Compilation is clean (no null-safety errors).
- [ ] Every test class has the Apache 2.0 license header wrapped in `@formatter:off/on`.
- [ ] Test method names follow the `method_condition_expected` three-segment pattern.
- [ ] Every test body has `// arrange`, `// act`, `// assert` comments.
- [ ] All tests for the same method/feature are inside a single `<editor-fold defaultstate="collapsed">` block.
- [ ] No `assertEquals` / `assertTrue` / `assertFalse` / `assertNotNull` anywhere.
- [ ] Exception tests with message assertions use `try { ...; fail(...); } catch`.
- [ ] All `Random` instances use a fixed seed.
- [ ] Data providers are added to `CommonDataProvider` (or project equivalent), not inlined in test classes.
- [ ] `@RunWith(DataProviderRunner.class)` is present **only** when `@UseDataProvider` is used.
- [ ] Empty `@Before` methods are removed.
- [ ] All nullable fields/returns in new production code are annotated with `@Nullable`.
- [ ] Array nullable annotations follow the `byte @Nullable []` placement convention.
- [ ] Logger in new production classes is `private final` with constructor injection (or setter as last resort).
- [ ] `@VisibleForTesting` is applied to any member exposed solely for tests.
- [ ] Async tests use `CountDownLatch` + `ExecutorService` + `Future`; no raw `Thread` or polling with `Thread.sleep`.
- [ ] Async socket tests use `findFreePort()` and project-specific timeout constants — no magic port numbers.
- [ ] Nested concrete implementations of abstract classes are private static inner classes inside the test class.
- [ ] `Objects.requireNonNull()` is used only in production code, never in tests.
- [ ] Multi-line expected strings use Java text blocks (`""" ... """`).
- [ ] Records with mutable third-party fields use `@SuppressWarnings("Immutable")` on the specific field.
- [ ] Behaviour injection in production constructors uses functional interfaces (`Consumer<T>`, `Function<T,R>`) rather than subclassing.
- [ ] Existing correct inline comments in modified test code are preserved — only removed if factually wrong or describing deleted code.

---

## Project-Specific Extensions

Each project may define additional conventions beyond this generic guide. Refer to your project's CLAUDE.md or supplementary guide files for:

- Custom marker annotations (e.g., `@OpenCLTest`, `@ToStringTest`, `@AwaitTimeTest`)
- Static test data constants (e.g., known addresses, keys, fixtures)
- Project-specific helper classes and test utilities
- Database or library-specific test patterns (LMDB, OpenCL, WebSocket, ZMQ, etc.)
- Configuration POJO naming conventions (e.g., C-prefix)
- Custom domain exceptions


================================================
FILE: .claude/skills/tdd/SKILL.md
================================================
---
name: tdd
description: Test-Driven Development workflow for BitcoinAddressFinder — delegates to the generic Java TDD skill and adds project-specific context
---

# TDD — Test-Driven Development for BitcoinAddressFinder

You are working on **BitcoinAddressFinder** (group `net.ladenthin`, Java 21, Maven).

## Generic Java TDD Guide

Follow all conventions from the generic Java TDD skill (`.claude/skills/java-tdd-guide/SKILL.md`). That guide covers:

- Red → Green → Refactor workflow
- File headers (Apache 2.0 license)
- Test framework stack (JUnit 4, DataProviderRunner, Hamcrest, Mockito)
- Test naming, AAA structure, editor folds
- Assertions (Hamcrest only), exception testing
- Data providers, named constants, DRY
- Logger injection (constructor over setter)
- Null safety (JSpecify + NullAway)
- Records, immutability, concurrency
- Import style, anti-patterns, completeness checklist

## Project-Specific Supplements

For BitcoinAddressFinder-specific conventions, also follow:

- **`CODE_WRITING_GUIDE.md`** — BitHelper radix constants, C-prefix configuration POJOs, custom domain exceptions, graceful shutdown (Interruptable), lambda callbacks
- **`TEST_WRITING_GUIDE.md`** — Marker annotations (@AwaitTimeTest, @ToStringTest, @OpenCLTest), timing/await tests, static address constants (StaticKey, P2PKH, P2SH, P2WPKH), platform assumptions, LMDB/OpenCL test patterns, producer test helpers, socket test utilities

## Package

```
net.ladenthin.bitcoinaddressfinder
```

## Build & Test

```bash
./mvnw compile       # compile (NullAway enforced)
./mvnw test          # run all tests
./mvnw test -Dnet.ladenthin.bitcoinaddressfinder.disableLMDBTest=true  # skip LMDB tests
```


================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
  - package-ecosystem: "maven" # See documentation for possible values
    directory: "/" # Location of package manifests
    schedule:
      interval: "weekly"


================================================
FILE: .github/workflows/assembly.yml
================================================
name: build assembly

on:
  push:
    branches:
      - main
      - 'releases/*'
  pull_request:
    branches:
      - '*'

env:
  javaversion: '21'
  javadistribution: 'temurin'

jobs:
  build:

    runs-on: 'ubuntu-latest'
    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK ${{ env.javaversion }} ${{ env.javadistribution }}
      uses: actions/setup-java@v4
      with:
        java-version: ${{ env.javaversion }}
        distribution: ${{ env.javadistribution }}
        cache: maven
    - name: Build with Maven
      run: mvn -B "-Dnet.ladenthin.bitcoinaddressfinder.disableLMDBTest=false" --update-snapshots test package assembly:single --file pom.xml

    - name: Archive binary
      uses: actions/upload-artifact@v4
      with:
        name: jar binaries
        path: target/*.jar
    - name: Upload Surefire Reports and JVM Crash Logs
      if: always()
      uses: actions/upload-artifact@v4
      with:
        name: surefire-and-crash-logs
        path: |
          target/surefire-reports/**
          hs_err_pid*.log


================================================
FILE: .github/workflows/claude-code-review.yml
================================================
name: Claude Code Review

on:
  pull_request:
    types: [opened, synchronize, ready_for_review, reopened]
    # Optional: Only run on specific file changes
    # paths:
    #   - "src/**/*.ts"
    #   - "src/**/*.tsx"
    #   - "src/**/*.js"
    #   - "src/**/*.jsx"

jobs:
  claude-review:
    # Optional: Filter by PR author
    # if: |
    #   github.event.pull_request.user.login == 'external-contributor' ||
    #   github.event.pull_request.user.login == 'new-developer' ||
    #   github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'

    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: Run Claude Code Review
        id: claude-review
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
          plugins: 'code-review@claude-code-plugins'
          prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
          # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
          # or https://code.claude.com/docs/en/cli-reference for available options



================================================
FILE: .github/workflows/claude.yml
================================================
name: Claude Code

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened, assigned]
  pull_request_review:
    types: [submitted]

jobs:
  claude:
    if: |
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
      (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write
      actions: read # Required for Claude to read CI results on PRs
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: Run Claude Code
        id: claude
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

          # This is an optional setting that allows Claude to read CI results on PRs
          additional_permissions: |
            actions: read

          # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
          # prompt: 'Update the pull request description to include a summary of changes.'

          # Optional: Add claude_args to customize behavior and configuration
          # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
          # or https://code.claude.com/docs/en/cli-reference for available options
          # claude_args: '--allowed-tools Bash(gh pr:*)'



================================================
FILE: .github/workflows/codeql.yml
================================================
name: "CodeQL"

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  schedule:
    - cron: "12 1 * * 0"

env:
  javaversion: '21'
  javadistribution: 'temurin'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ java ]

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up JDK ${{ env.javaversion }} ${{ env.javadistribution }}
        uses: actions/setup-java@v4
        with:
          java-version: ${{ env.javaversion }}
          distribution: ${{ env.javadistribution }}

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          queries: +security-and-quality

      - name: Autobuild
        uses: github/codeql-action/autobuild@v3

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3
        with:
          category: "/language:${{ matrix.language }}"


================================================
FILE: .github/workflows/coverage.yml
================================================
name: code coverage

on:
  push:
    branches:
      - main
      - 'releases/*'
  pull_request:
    branches:
      - '*'

env:
  javaversion: '21'
  javadistribution: 'temurin'

jobs:
  build:

    runs-on: 'ubuntu-latest'
    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK ${{ env.javaversion }} ${{ env.javadistribution }}
      uses: actions/setup-java@v4
      with:
        java-version: ${{ env.javaversion }}
        distribution: ${{ env.javadistribution }}
        cache: maven
    - name: Build with Maven
      run: mvn -B "-Dnet.ladenthin.bitcoinaddressfinder.disableLMDBTest=true" --update-snapshots test package jacoco:report --file pom.xml
    - name: Upload Surefire Reports and JVM Crash Logs
      if: always()
      uses: actions/upload-artifact@v4
      with:
        name: surefire-and-crash-logs
        path: |
          target/surefire-reports/**
          hs_err_pid*.log
    # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
    - name: Update dependency graph
      uses: advanced-security/maven-dependency-submission-action@0b9cd8f382c5d2016fa77ebf8a0f2804452fefef

    # https://github.com/marketplace/actions/coveralls-github-action
    - name: Coveralls GitHub Action
      uses: coverallsapp/github-action@v2
      with:
        github-token: ${{ secrets.COVERALLS_TOKEN }}
        file: target/site/jacoco/jacoco.xml
        format: jacoco

    # https://github.com/codecov/codecov-action
    - name: Codecov GitHub Action
      uses: codecov/codecov-action@v5
      with:
        token: ${{ secrets.CODECOV_TOKEN }}


================================================
FILE: .github/workflows/matrixci.yml
================================================
name: matrix CI

on:
  push:
    branches:
      - main
      - 'releases/*'
  pull_request:
    branches:
      - '*'

jobs:
  build:

    strategy:
      # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategyfail-fast
      fail-fast: false
      # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs
      matrix:
        # https://github.com/actions/setup-java#supported-distributions
        javaversion: [ '21' ]
        # disabled for now for performance reason: javadistribution: ['adopt', 'adopt-openj9', 'corretto', 'dragonwell', 'liberica', 'microsoft', 'temurin', 'zulu'] # internally 'adopt-hotspot' is the same as 'adopt'
        javadistribution: ['temurin']
        # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
        # disabled for now for performance reason: os: [macos-latest, ubuntu-latest, windows-latest]
        os: [windows-latest]
        exclude:
          - javadistribution: 'microsoft'
            os: 'macos-latest'
          - javadistribution: 'dragonwell'
            os: 'macos-latest'

    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK ${{ matrix.javaversion }} ${{ matrix.javadistribution }}
      uses: actions/setup-java@v4
      with:
        java-version: ${{ matrix.javaversion }}
        distribution: ${{ matrix.javadistribution }}
        cache: maven
    - name: Build with Maven
      run: mvn -B --no-transfer-progress "-Dnet.ladenthin.bitcoinaddressfinder.disableLMDBTest=false" test --file pom.xml
    - name: Upload Surefire Reports and JVM Crash Logs
      if: always()
      uses: actions/upload-artifact@v4
      with:
        name: surefire-reports-${{ matrix.os }}-${{ matrix.javadistribution }}-java${{ matrix.javaversion }}
        path: |
            target/surefire-reports/**
            hs_err_pid*.log


================================================
FILE: .gitignore
================================================
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

/target/
/bin/

# IDEA files
/.idea/
*.iml

# Eclipse files
.classpath
.project
.settings

# Netbeans files
nbactions.xml


================================================
FILE: .mvn/jvm.config
================================================
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens  jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
--add-opens  jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED


================================================
FILE: CLAUDE.md
================================================
# CLAUDE.md — BitcoinAddressFinder

This document provides guidance for AI assistants working on the BitcoinAddressFinder codebase.

---

## Project Overview

**BitcoinAddressFinder** is a high-performance, open-source tool for scanning Bitcoin and altcoin private keys and checking whether the derived addresses have balances. It supports 100+ cryptocurrencies and uses both CPU (Java) and GPU (OpenCL) key generation strategies.

- **Group ID:** `net.ladenthin`
- **Artifact ID:** `bitcoinaddressfinder`
- **Version:** 1.5.0
- **Java:** 21
- **License:** Apache 2.0
- **Author:** Bernard Ladenthin (Copyright 2017–2025)
- **Main class:** `net.ladenthin.bitcoinaddressfinder.cli.Main`

---

## Build System

The project uses **Maven** (minimum 3.6.3) with a Maven Wrapper.

### Common Commands

```bash
# Compile only
./mvnw compile

# Run all tests
./mvnw test

# Build fat JAR with all dependencies
./mvnw package -P assembly

# Build without tests
./mvnw package -DskipTests

# Generate coverage report
./mvnw test jacoco:report

# Skip LMDB-specific tests (useful when LMDB native libs unavailable)
./mvnw test -Dnet.ladenthin.bitcoinaddressfinder.disableLMDBTest=true
```

### JVM / Compiler Flags

Tests run with `-Xmx2g -Xms1g` and several `--add-opens` / `--add-exports` to allow LMDB and internal module access. These are configured in `pom.xml` (`<argLine>`) and `.mvn/jvm.config`.

**Error Prone** static analysis with **NullAway** is active at compile time:
- All code in `net.ladenthin` packages must carry proper `@Nullable` / `@NonNull` annotations.
- Compilation will fail on potential null-pointer issues unless annotated.

---

## Project Structure

```
BitcoinAddressFinder/
├── src/
│   ├── main/
│   │   ├── java/net/ladenthin/bitcoinaddressfinder/
│   │   │   ├── cli/                  # CLI entry point (Main.java)
│   │   │   ├── configuration/        # Config POJOs (C-prefixed)
│   │   │   ├── keyproducer/          # Key generation strategies
│   │   │   ├── persistence/          # Persistence abstraction + LMDB impl
│   │   │   ├── opencl/               # OpenCL device/platform wrappers
│   │   │   ├── eckey/                # Secp256k1 ECC utilities
│   │   │   └── *.java                # Core domain classes
│   │   └── resources/
│   │       ├── *.cl / *.h            # OpenCL kernels and headers
│   │       └── simplelogger.properties
│   └── test/
│       └── java/net/ladenthin/bitcoinaddressfinder/
│           └── *.java                # JUnit 4 tests
├── examples/                         # Sample JSON configs and run scripts
│   ├── config_*.json
│   ├── run_*.bat
│   ├── logbackConfiguration.xml
│   ├── addresses/                    # Sample address files
│   └── secrets/                      # Sample secrets files
├── helper/                           # Utility scripts (address scraping, wallet ops)
├── .github/workflows/                # CI/CD pipelines
├── pom.xml
├── .mvn/jvm.config
└── README.md
```

---

## Core Architecture

### Producer–Consumer Pattern

The central design separates **key production** from **address checking**:

```
[Producers] → LinkedBlockingQueue<byte[]> → [ConsumerJava]
```

- **`Producer` (interface)** — generates private keys and pushes them to the queue.
- **`Consumer` (interface)** — reads keys from the queue, derives addresses, and checks the LMDB database.
- **`Finder`** — orchestrates producers and consumers, manages thread pools, and handles shutdown.

### Key Components

| Class | Role |
|---|---|
| `cli/Main.java` | Entry point; parses args, loads config, starts `Finder` |
| `Finder.java` | Orchestrator; starts/stops producers and consumer |
| `ProducerJava.java` | CPU-based key generator using `KeyProducer` strategies |
| `ProducerOpenCL.java` | GPU-accelerated key generator via JOCL |
| `ProducerJavaSecretsFiles.java` | Reads keys from a secrets file |
| `ConsumerJava.java` | Derives addresses, queries LMDB, logs hits |
| `PublicKeyBytes.java` | Public key representation and address derivation |
| `KeyUtility.java` | Cryptographic helpers (record class) |
| `OpenCLContext.java` | OpenCL context setup and kernel management |
| `OpenClTask.java` | Executes a batch of key operations on the GPU |
| `AddressFilesToLMDB.java` | Imports address files into LMDB database |
| `LMDBToAddressFile.java` | Exports LMDB database to address files |
| `NetworkParameterFactory.java` | Creates BitcoinJ `NetworkParameters` for 100+ coins |
| `SeparatorFormat.java` | Parses address file formats (various separators) |
| `Shutdown.java` | Graceful shutdown logic with 30-second timeout |

### Key Producer Strategies (`keyproducer/`)

| Class | Strategy |
|---|---|
| `KeyProducerJavaRandom` | `SecureRandom` private key generation |
| `KeyProducerJavaIncremental` | Sequential range scanning |
| `KeyProducerJavaBip39` | BIP39 mnemonic phrase derivation |
| `KeyProducerJavaSocket` | TCP socket input |
| `KeyProducerJavaWebSocket` | WebSocket server input |
| `KeyProducerJavaZmq` | ZeroMQ message broker input |

### Configuration Classes (`configuration/`)

All configuration POJOs are prefixed with `C`:

| Class | Purpose |
|---|---|
| `CConfiguration` | Root config object |
| `CCommand` | Command enum: `Find`, `AddressFilesToLMDB`, `LMDBToAddressFile`, `OpenCLInfo` |
| `CFinder` | Finder-level settings |
| `CConsumerJava` | Consumer settings |
| `CProducer` | Abstract producer settings |
| `CProducerJava` | Java producer settings |
| `CProducerOpenCL` | OpenCL producer settings |
| `CProducerJavaSecretsFiles` | Secrets file producer settings |
| `CKeyProducerJava*` | Per-strategy key producer settings |
| `CLMDBConfigurationReadOnly/Write` | LMDB database config |

### Persistence Layer (`persistence/`)

- `Persistence` interface abstracts database operations.
- `LMDBPersistence` implements high-performance O(1) address lookups using LMDB.
- `PersistenceUtils` provides helper methods.

### Helper Classes (Validation & Utilities)

Helper classes encapsulate single-responsibility validation and utility logic, improving testability and separation of concerns:

| Class | Purpose | Injection Pattern |
|---|---|---|
| `PrivateKeyValidator` | Non-static validation of private keys against secp256k1 constraints | Created in constructors where needed; no external dependencies |
| `KeyUtility` (record) | Cryptographic utilities requiring network/buffer context | Injected as dependency into producers/consumers |
| `ByteBufferUtility` | ByteBuffer conversion utilities | Passed as constructor parameter |

**Design Pattern: Static to Helper Migration**

Certain utility methods that were previously static (e.g., key range validation) have been refactored into dedicated helper classes as non-static instance methods. This improves:
- **Testability**: Instances are easier to mock in tests
- **Clarity**: Dependencies are explicit
- **Extensibility**: Future subclasses can override behavior

Example: `PrivateKeyValidator` contains the following methods (formerly static in `KeyUtility`):
- `getMaxPrivateKeyForBatchSize(int batchSizeInBits)`
- `isInvalidWithBatchSize(BigInteger, BigInteger)`
- `isOutsidePrivateKeyRange(BigInteger)`
- `returnValidPrivateKey(BigInteger)`
- `replaceInvalidPrivateKeys(BigInteger[])`

Callers instantiate `PrivateKeyValidator` directly (stateless) or receive it via dependency injection where appropriate.

---

## Configuration Format

The tool is driven entirely by JSON configuration files. The `CCommand` enum selects the operation mode.

Example (find with 8 CPU producers):
```json
{
  "command": "Find",
  "finder": {
    "producers": [
      {
        "producerJava": {
          "threads": 8,
          "keyProducers": [{ "keyProducerJavaRandom": {} }]
        }
      }
    ],
    "consumerJava": {
      "lmdbConfigurationReadOnly": { "lmdbDirectory": "/path/to/lmdb" }
    }
  }
}
```

See `examples/config_*.json` for all configuration variants.

---

## Testing

### Frameworks

- **JUnit 4** (4.13.2) — test runner
- **Hamcrest** (3.0) — matchers
- **Mockito** (5.22.0) — mocking
- **junit-dataprovider** (1.13.1) — data-driven tests

### Conventions

- Tests use forked JVMs (1 fork, no reuse) for isolation.
- Test timeout: 60 seconds per test.
- Base/utility test classes: `LMDBBase`, `BIP39DataProvider`, `TestTimeProvider`, `KeyProducerTestUtility`.
- LMDB tests can be skipped with system property:
  ```
  -Dnet.ladenthin.bitcoinaddressfinder.disableLMDBTest=true
  ```
- Test ratio is approximately 1.7:1 (test lines to source lines). New code should have corresponding tests.

---

## Code Conventions

### Null Safety

- Use **JSpecify** annotations: `@Nullable` (from `org.jspecify.annotations`) for optional values, `@NonNull` is the default.
- **NullAway** enforces null safety at compile time for the entire `net.ladenthin` package tree. Unannotated code will cause compilation errors.

### Naming

- Configuration POJOs: prefix `C` (e.g., `CProducerJava`, `CKeyProducerJavaRandom`).
- Producer implementations: suffix with type (e.g., `ProducerJava`, `ProducerOpenCL`).
- Key producer strategies: `KeyProducerJava<Strategy>` pattern.

### Annotations

- `@VisibleForTesting` — marks package-private or protected members exposed only for testing.
- `@ToStringTest` — marks fields that should be verified in `toString()` tests.
- `@Nullable` / implicit `@NonNull` from JSpecify.

### License Headers

All source files must include the Apache 2.0 license header. See any existing source file for the exact template. Use `// @formatter:off` / `// @formatter:on` around the header to exclude it from auto-formatting.

### Error Handling

Use custom domain exceptions rather than generic ones:
- `KeyProducerIdNullException`
- `KeyProducerIdIsNotUniqueException`
- `KeyProducerIdUnknownException`
- `NoMoreSecretsAvailableException`
- `PrivateKeyTooLargeException`
- `UnknownSecretFormatException`

### Concurrency

- `LinkedBlockingQueue<byte[]>` for producer → consumer communication.
- `ExecutorService` / `ThreadPoolExecutor` for thread pool management.
- `AtomicLong` for thread-safe statistics counters.
- `CountDownLatch` for shutdown synchronization.
- Do not introduce raw `Thread` usage; use executor services.

### Records

Some utility classes are implemented as Java `record` types (e.g., `KeyUtility`). Prefer records for immutable value objects.

---

## OpenCL / GPU Code

OpenCL kernels live in `src/main/resources/` as `.cl` and `.h` files:

| File | Purpose |
|---|---|
| `inc_ecc_secp256k1custom.cl` | Elliptic curve scalar multiplication |
| `inc_hash_sha256.cl` | SHA-256 (ported from hashcat) |
| `inc_hash_ripemd160.cl` | RIPEMD-160 (ported from hashcat) |
| `inc_defines.h` | Common preprocessor defines |
| `inc_platform.cl` | Platform-specific abstractions |
| `inc_types.h` | OpenCL type definitions |

GPU code is bound through JOCL (`jocl` 2.0.6). `OpenCLBuilder` constructs the platform/device hierarchy; `OpenCLContext` manages kernel compilation and execution; `OpenClTask` processes a batch of keys on the GPU.

---

## CI/CD Pipelines (`.github/workflows/`)

| Workflow | Trigger | Purpose |
|---|---|---|
| `assembly.yml` | Push to `main`/`releases/*`, all PRs | Compile, test, build fat JAR, upload artifacts |
| `matrixci.yml` | Push/PR | Matrix test across 8 JVM distributions × 3 OS |
| `coverage.yml` | Push/PR | JaCoCo coverage + Coveralls upload |
| `codeql.yml` | Schedule/Push | GitHub CodeQL security scanning |
| `claude-code-review.yml` | PR | AI-powered code review |
| `claude.yml` | Issue/PR comment with `@claude` | Claude Code interactive assistant |

The matrix CI tests Java 21 on:
- **Distributions:** adopt, adopt-openj9, corretto, dragonwell, liberica, microsoft, temurin, zulu
- **OS:** Ubuntu, Windows, macOS (some combos excluded for incompatibility)

---

## Dependencies Summary

| Dependency | Version | Purpose |
|---|---|---|
| `bitcoinj-core` | 0.17 | Bitcoin crypto, address derivation |
| `lmdbjava` | 0.9.3 | LMDB database bindings |
| `jocl` | 2.0.6 | Java OpenCL bindings |
| `gson` | 2.13.2 | JSON config parsing |
| `snakeyaml` | 2.6 | YAML config parsing |
| `guava` | 33.5.0-jre | Google core utilities |
| `commons-codec` | 1.21.0 | Base58, hex encoding |
| `commons-io` | 2.21.0 | I/O utilities |
| `Java-WebSocket` | 1.6.0 | WebSocket producer |
| `jeromq` | 0.6.0 | ZeroMQ producer |
| `jspecify` | 1.0.0 | Nullness annotations |
| `slf4j-api` | 2.0.17 | Logging facade |
| `logback-classic` | 1.5.32 | SLF4J implementation |

Test-only:
| `junit` | 4.13.2 | Test runner |
| `hamcrest` | 3.0 | Assertion matchers |
| `mockito-core` | 5.22.0 | Mocking |
| `junit-dataprovider` | 1.13.1 | Data-driven tests |

---

## Running the Tool

```bash
# Build fat JAR
./mvnw package -P assembly -DskipTests

# Run (replace config path as needed)
java -jar target/bitcoinaddressfinder-1.5.0-jar-with-dependencies.jar \
  examples/config_Find_8CPUProducer.json
```

Pre-built run scripts exist in `examples/` for each operation mode (`run_*.bat` for Windows).

---

## Test Writing Compliance

After modifying or creating any `*Test.java` file, automatically verify that all rules from the generic Java TDD skill (`.claude/skills/java-tdd-guide/SKILL.md`) **and** the project-specific supplement (`TEST_WRITING_GUIDE.md`) are applied to the modified test class. Apply all fixable violations on your own without asking. Only report violations that cannot be resolved without a large refactoring. Consider the task complete only after all auto-fixable rules are satisfied.

---

## Code Writing Compliance

After modifying or creating any production `.java` file, automatically verify that all rules from the generic Java TDD skill (`.claude/skills/java-tdd-guide/SKILL.md`) **and** the project-specific supplement (`CODE_WRITING_GUIDE.md`) are applied to the modified class. Apply all fixable violations on your own without asking. Only report violations that cannot be resolved without a large refactoring. Consider the task complete only after all auto-fixable rules are satisfied.

---

## Pull Request Workflow

### Step 1 — Detect whether `gh` is available

```bash
gh --version 2>/dev/null && echo "gh available" || echo "gh not available"
```

If `gh` is **not** available (e.g. local proxy remote), inform the user and stop. Do not attempt the remaining steps.

### Step 2 — Create the PR

Always create a PR immediately after the first push to a feature branch:

```bash
gh pr create \
  --title "<concise summary, ≤70 chars>" \
  --body "$(cat <<'EOF'
## Summary
- <bullet: what changed>
- <bullet: why>

## Test plan
- [ ] Affected test classes pass
- [ ] Full CI matrix passes

<session URL>
EOF
)"
```

Note the PR number printed — you need it in the next steps.

### Step 3 — Wait for all checks to complete

```bash
gh pr checks <PR-number> --watch --interval 30
```

If `--watch` is unavailable in the installed `gh` version, poll manually:

```bash
while gh pr checks <PR-number> | grep -qE "pending|in_progress|queued"; do
  sleep 30
done
gh pr checks <PR-number>
```

### Step 4 — Triage failures

For each failing check, fetch the log:

```bash
gh run list --branch <branch-name> --limit 10
gh run view <run-id> --log-failed
```

For **CodeQL annotation** failures, pull structured annotations directly (avoids parsing raw logs):

```bash
# get the annotations URL for the CodeQL check on the latest commit
gh api repos/{owner}/{repo}/commits/<sha>/check-runs \
  --jq '.check_runs[] | select(.name | test("CodeQL")) | .output.annotations_url'

# fetch the annotations (path, line number, message)
gh api <annotations-url> \
  --jq '.[] | {path: .path, line: .start_line, message: .message}'
```

### Step 5 — Fix, commit, push, repeat

1. Read the failure message or annotation.
2. Apply the fix.
3. Commit and push:
   ```bash
   git add <files>
   git commit -m "Fix <check-name>: <short description>"
   git push
   ```
4. Return to **Step 3** and wait for the re-run.
5. Repeat until `gh pr checks <PR-number>` shows every check as ✅ pass.

### Step 6 — Report to the user

Once all checks pass, summarise what was fixed and why. If a failure **cannot** be fixed automatically (e.g. requires a large refactor, changes public API, or disabling a security check) stop, explain the situation, and ask for direction instead of silently suppressing or working around it.

---

## Key Design Principles

1. **Performance first** — key generation is the hot path; minimize allocations, use byte arrays not objects.
2. **Pluggable producers** — new key generation strategies implement `KeyProducer` and `Producer`; register in config classes.
3. **Single consumer** — `ConsumerJava` is intentionally single-threaded to avoid LMDB contention; producers are the parallelism point.
4. **Graceful shutdown** — always implement `Interruptable`; propagate interrupts from `Main` → `Finder` → all producers/consumers.
5. **Null safety is required** — NullAway is error-level; annotate all nullable return types and parameters.
6. **Configuration-driven** — behaviour changes belong in config, not in code conditionals.


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[bernard.ladenthin@gmail.com](mailto:bernard.ladenthin@gmail.com).
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: CODE_WRITING_GUIDE.md
================================================
# Code Writing Guide — BitcoinAddressFinder (Project-Specific Supplement)

This guide contains **project-specific** production code conventions that supplement the generic Java TDD skill (`.claude/skills/java-tdd-guide.md`). For general Java conventions (named constants, logger injection, null safety, records, concurrency, etc.), refer to the generic guide.

---

## 1. Radix Constants — BitHelper

Radix values (`16`, `10`, `2`) must always be referenced through `BitHelper` constants — never as bare integer literals:

```java
// ❌ BAD
new BigInteger("FF", 16);

// ✅ GOOD
new BigInteger("FF", BitHelper.RADIX_HEX);
```

Available constants:
- `BitHelper.RADIX_HEX` (16)
- `BitHelper.RADIX_DECIMAL` (10)
- `BitHelper.RADIX_BINARY` (2)

---

## 2. Configuration Objects — C-Prefix POJOs

All new features are driven by a C-prefixed configuration POJO:

```java
public class CMyFeature {
    public int threads = 1;
    public @Nullable String optionalParam;
}

// Constructor receives the config as first argument:
public MyFeature(CMyFeature config, KeyUtility keyUtility, Logger logger) {
    this.config = config;
    this.keyUtility = keyUtility;
    this.logger = logger;
}
```

---

## 3. Custom Domain Exceptions

Use project-specific exception types rather than generic ones:

| Exception | When to use |
|---|---|
| `KeyProducerIdNullException` | Key producer ID is null |
| `KeyProducerIdIsNotUniqueException` | Duplicate key producer ID |
| `KeyProducerIdUnknownException` | Unrecognized key producer ID |
| `NoMoreSecretsAvailableException` | Secret source exhausted |
| `PrivateKeyTooLargeException` | Private key exceeds secp256k1 range |
| `UnknownSecretFormatException` | Unrecognized secret format |
| `AddressFormatNotAcceptedException` | Invalid address format |

Create a new domain exception rather than throwing `IllegalArgumentException` or `RuntimeException` when a more specific type makes sense.

---

## 4. Graceful Shutdown — Interruptable Interface

All Producer/Consumer implementations must implement `Interruptable`:

```java
public class MyProducer extends AbstractProducer implements Interruptable {
    @Override
    public void interrupt() {
        // signal the work loop to stop
    }
}
```

---

## 5. Lambda Callbacks in Production Constructors

Inject behaviour via functional interfaces rather than subclassing:

```java
public AddressFile(
    File file,
    ReadStatistic readStatistic,
    Network network,
    Consumer<AddressToCoin> addressConsumer,
    Consumer<String> rejectedLineConsumer
) { ... }
```


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS



APPENDIX A: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.



APPENDIX B: Additional licenses relevant to this product:

    This product includes a number of source files with code that has been 
    adapted from 3rd party sources including sources that may be subject 
    to different copyright notices and license terms. Your use of 
    the source code for these subcomponents is subject to the terms and
    conditions of the following licenses.



    =============================================================
    Apache License version 2.0 (see above)
    =============================================================
    * [TEMPLATE-PROJECT]

    Code locations:
    -------------------------------------------------------------
    * [TEMPLATE-LOCATION]



    =============================================================
    BSD-2-Clause License
    =============================================================
    All rights reserved.

    BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)

    Redistribution and use in source and binary forms, with or without modification,
    are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this
      list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright notice, this
      list of conditions and the following disclaimer in the documentation and/or
      other materials provided with the distribution.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
    ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    * [TEMPLATE-PROJECT]
    Code locations:
    -------------------------------------------------------------
    * [TEMPLATE-LOCATION]





    =============================================================
    MIT License
    =============================================================

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 

    -------------------------------------------------------------
    * hashcat Copyright (c) 2015-2020 Jens Steube
    Code locations:
    -------------------------------------------------------------
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_common.cl
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_common.h
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_defines.h
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_ecc_secp256k1.cl
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_ecc_secp256k1.h
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_platform.cl
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_platform.h
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_types.h
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_vendor.h
    * https://github.com/hashcat/hashcat/blob/master/OpenCL/inc_vendor.h

    =============================================================
    Public Domain (optional)
    =============================================================
    * [TEMPLATE-PROJECT]

    Code locations:
    -------------------------------------------------------------
    * [TEMPLATE-LOCATION]


================================================
FILE: README.md
================================================
# BitcoinAddressFinder
> 🚀 Fast address finder for Bitcoin and altcoins using OpenCL & Java – includes vanity address generation, balance checking, and offline support.
<!-- =========================== Build & Environment =========================== -->
[![OpenJDK](https://img.shields.io/badge/OpenJDK-21-blue)]()
[![JUnit](https://img.shields.io/badge/tested%20with-JUnit4-yellow)]()
[![Assembly](https://github.com/bernardladenthin/BitcoinAddressFinder/actions/workflows/assembly.yml/badge.svg)](https://github.com/bernardladenthin/BitcoinAddressFinder/actions/workflows/assembly.yml)
[![Coverage](https://github.com/bernardladenthin/BitcoinAddressFinder/actions/workflows/coverage.yml/badge.svg)](https://github.com/bernardladenthin/BitcoinAddressFinder/actions/workflows/coverage.yml)
[![Matrix CI](https://github.com/bernardladenthin/BitcoinAddressFinder/actions/workflows/matrixci.yml/badge.svg)](https://github.com/bernardladenthin/BitcoinAddressFinder/actions/workflows/matrixci.yml)
<!-- =========================== Test Coverage =========================== -->
[![Coverage Status](https://coveralls.io/repos/github/bernardladenthin/BitcoinAddressFinder/badge.svg?branch=main)](https://coveralls.io/github/bernardladenthin/BitcoinAddressFinder?branch=main)
[![codecov](https://codecov.io/gh/bernardladenthin/BitcoinAddressFinder/graph/badge.svg?token=RRCR4ZC28T)](https://codecov.io/gh/bernardladenthin/BitcoinAddressFinder)
<!-- =========================== Package & Release =========================== -->
[![Maven Central](https://img.shields.io/maven-central/v/net.ladenthin/bitcoinaddressfinder.svg)](https://search.maven.org/artifact/net.ladenthin/bitcoinaddressfinder)
[![Release Date](https://img.shields.io/github/release-date/bernardladenthin/BitcoinAddressFinder)]()
[![Last Commit](https://img.shields.io/github/last-commit/bernardladenthin/BitcoinAddressFinder)]()
<!-- =========================== Quality & Analysis =========================== -->
[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=bernardladenthin_BitcoinAddressFinder&metric=alert_status)](https://sonarcloud.io/dashboard?id=bernardladenthin_BitcoinAddressFinder)
[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=bernardladenthin_BitcoinAddressFinder&metric=code_smells)](https://sonarcloud.io/dashboard?id=bernardladenthin_BitcoinAddressFinder)
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=bernardladenthin_BitcoinAddressFinder&metric=security_rating)](https://sonarcloud.io/dashboard?id=bernardladenthin_BitcoinAddressFinder)
<!-- =========================== Security & Compliance =========================== -->
[![Known Vulnerabilities](https://snyk.io/test/github/bernardladenthin/BitcoinAddressFinder/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/bernardladenthin/BitcoinAddressFinder?targetFile=pom.xml)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fbernardladenthin%2FBitcoinAddressFinder.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fbernardladenthin%2FBitcoinAddressFinder?ref=badge_shield)
[![Dependencies](https://img.shields.io/librariesio/github/bernardladenthin/BitcoinAddressFinder)](https://libraries.io/github/bernardladenthin/BitcoinAddressFinder)
<!-- =========================== License & Contribution =========================== -->
[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-orange)](./LICENSE)
[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/bernardladenthin/BitcoinAddressFinder)
<!-- =========================== Sustainability =========================== -->
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/10413/badge)](https://www.bestpractices.dev/projects/10413)
[![Treeware](https://img.shields.io/badge/dynamic/json?color=brightgreen&label=Treeware&query=%24.total&url=https%3A%2F%2Fpublic.offset.earth%2Fusers%2Ftreeware%2Ftrees)](https://treeware.earth)
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)
<!--
TODO:
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1234/badge)](https://bestpractices.coreinfrastructure.org/projects/1234)
-->

---

## Table of Contents
- [About BitcoinAddressFinder](#about-bitcoinaddressfinder)
- [Requirements](#requirements)
- [Quickstart](#quickstart)
- [Features](#features)
- [Address Database](#address-database)
  - [Import](#import)
  - [Create the Database by Yourself](#create-the-database-by-yourself)
  - [Export](#export)
  - [Use My Prepared Database](#use-my-prepared-database)
    - [Light Database](#light-database)
    - [Full Database](#full-database)
- [Pages and Projects for Address Lists](#pages-and-projects-to-get-lists-dumps-of-pubkeyhash-addresses)
- [Find Addresses](#find-addresses)
  - [Mixed Modes](#mixed-modes)
  - [Key Range](#key-range)
  - [OpenCL Acceleration](#opencl-acceleration)
    - [Built-in Self-Test (BIST)](#built-in-self-test-bist)
    - [Performance Benchmarks](#performance-benchmarks)
- [Collision Probability and Security Considerations](#collision-probability-and-security-considerations)
- [Similar Projects](#similar-projects)
  - [Deep Learning Private Key Prediction](#deep-learning-private-key-prediction)
- [Known Issues](#known-issues)
  - [Hybrid Graphics Performance (Low Throughput)](#hybrid-graphics-performance-low-throughput)
- [Future Improvements](#future-improvements)
  - [KeyProvider](#keyprovider)
- [Legal](#legal)
  - [Permitted Use Cases](#️-permitted-use-cases)
  - [Prohibited Use Cases](#-prohibited-use-cases)
  - [Legal References by Jurisdiction](#legal-references-by-jurisdiction)
- [License](#license)

---

## About BitcoinAddressFinder
**BitcoinAddressFinder** is a free, high-performance tool for scanning random private keys across a wide range of cryptocurrencies — including Bitcoin, Bitcoin Cash, Bitcoin SV, Litecoin, Dogecoin, Dash, Zcash, and many more.

Its core purpose is to generate both **compressed** and **uncompressed** addresses with maximum efficiency, combining the portability of the **Java Virtual Machine (JVM)** with **OpenCL-powered GPU acceleration**.

Each generated address is checked against a high-speed **LMDB** database to detect whether it has ever been used — identifying possible balances, known keyspaces, and even **RIPEMD160 hash collisions**.

🔍 Whether you're generating vanity addresses, verifying address usage, or experimenting with cryptographic edge cases, **BitcoinAddressFinder** is built for **speed**, **flexibility**, and **fully offline operation**.

> 🔐 Runs air-gapped · ⚡ GPU-accelerated · 🧪 Unit-tested · 🛠️ Extensible

**Made with ❤️ in Germany** 
 
Copyright (c) 2017-2025 Bernard Ladenthin

## Requirements
- **Java 21 or newer** is required to run BitcoinAddressFinder.  
  Older versions such as Java 8, 11, or 17 are not supported.

- **🚀 OpenCL (optional)**:  
  You can run this software in either **CPU-only** mode or with **GPU acceleration via OpenCL** for significantly enhanced performance.

  When OpenCL is enabled:
  - **Elliptic Curve Key Generation** is offloaded to one or more OpenCL-capable devices (e.g., GPUs), dramatically boosting key scanning throughput.
  - **SHA-256** and **RIPEMD-160** hashing operations are also offloaded to the GPU, further reducing CPU load and increasing overall efficiency.
  - **Multi-GPU setups are fully supported** — each device can be configured individually, enabling efficient parallelization and scalability across multiple GPUs.

## Quickstart
1. Download Software
- Release: Download the binary (jar) from https://github.com/bernardladenthin/BitcoinAddressFinder/releases
- Nightly: Download the binary (jar) newest build from github: https://nightly.link/bernardladenthin/BitcoinAddressFinder/workflows/assembly/main/jar%20binaries.zip
2. Download and extract the light database from https://github.com/bernardladenthin/BitcoinAddressFinder#use-my-prepared-database
3. Download a configuration set like:
- [`logbackConfiguration.xml`](https://github.com/bernardladenthin/BitcoinAddressFinder/blob/main/examples/logbackConfiguration.xml)
- [`config_Find_1OpenCLDevice.json`](https://github.com/bernardladenthin/BitcoinAddressFinder/blob/main/examples/config_Find_1OpenCLDevice.json)
- [`run_Find_1OpenCLDevice.bat`](https://github.com/bernardladenthin/BitcoinAddressFinder/blob/main/examples/run_Find_1OpenCLDevice.bat)
4. Put all in one directory like the following structure
  * Downloads
    * lmdb
      * data.mdb
      * lock.mdb
    * bitcoinaddressfinder-1.4.0-jar-with-dependencies.jar
    * logbackConfiguration.xml
    * config_Find_1OpenCLDevice.js
    * run_Find_1OpenCLDevice.bat
5. Run the file run_Find_1OpenCLDevice.bat

## ✨ Features
* 📐 Supports blockchain addresses based on [secp256k1](https://en.bitcoin.it/wiki/Secp256k1)
* 🛡️ Unit-tested, trusted open source that can be compiled easily by yourself
* 🎯 Vanity generation of Bitcoin addresses using regex patterns
* 🔌 Runs entirely offline — no internet connection is required or used. Suitable for air-gapped systems and isolated environments — even in a bunker with a generator and zero connectivity.
* 🤹 No synchronization required to run multiple instances. Random numbers are used, so no coordinated search strategy is needed — just run it on multiple machines
* ⚡ Checks a high-performance database of known addresses to detect already used ones
* 📦 Portable, platform-independent, runs on the JVM
* 🔁 Generates both uncompressed and compressed keys simultaneously
* 🧮 EC key generation via:
  * 🧵 Multiple CPU threads
  * 🖥️ Multiple OpenCL devices (optional)

### ⚡ ECC Scalar Multiplication Optimizations
To accelerate **elliptic curve scalar multiplication** (`k·G`, i.e. private key × base point), the OpenCL kernel applies the following optimizations:

- **Windowed Non-Adjacent Form (wNAF)**:  
  The scalar `k` is converted to a signed digit representation using a **window size of 4**.  
  This results in digits from the set `{±1, ±3, ±5, ±7}`, with at least one zero between non-zero digits.  
  This reduces the number of costly additions during multiplication.  
  [Further explanation of wNAF on crypto.stackexchange.com](https://crypto.stackexchange.com/questions/82013/simple-explanation-of-sliding-window-and-wnaf-methods-of-elliptic-curve-point-mu)

- **Precomputed Table**:  
  The kernel precomputes and stores the following multiples of the base point `G`:  
  `±1·G`, `±3·G`, `±5·G`, `±7·G`  
  These are stored in the `secp256k1_t` structure and reused during scalar multiplication.

- **Left-to-Right Scalar Multiplication**:  
  The multiplication loop scans the wNAF digits from most to least significant:  
  - Each iteration **always doubles** the current point.  
  - If the current digit is non-zero, it **adds the matching precomputed point**.

- **Optimized for GPGPU (not constant-time)**:  
  To prioritize speed on OpenCL/CUDA devices, this implementation is **not constant-time** and may be vulnerable to side-channel attacks in adversarial environments.

- **Use of Constant Memory**:  
  Precomputed points are stored in **constant GPU memory** (`__constant` via `CONSTANT_AS`), allowing fast access by all threads in a workgroup.

### 🔄 Scalar Walker per Kernel (`loopCount`)
The OpenCL kernel supports a **loop-based scalar strategy** controlled by the `loopCount` parameter. Each GPU thread generates multiple EC keys by:

- Computing the first key via full scalar multiplication: `P₀ = k₀·G` (using `point_mul_xy`)  
- Computing subsequent keys via efficient affine additions: `Pₙ₊₁ = Pₙ + G` (using `point_add_xy`)

This enables high-throughput, grid-parallel **linear keyspace traversal** like:  
`k₀·G, (k₀ + 1)·G, ..., (k₀ + loopCount - 1)·G`

Example:  
- If `loopCount = 8`, each thread generates 8 keys  
- Grid size is reduced by a factor of 8  
- All results are written to global memory

> ✅ Lower `loopCount` values like 4 or 8 are often ideal.  
> ❌ Higher values may reduce GPU occupancy due to fewer active threads.

### 🚀 MSB-Zero Optimization
To accelerate elliptic curve multiplication, BitcoinAddressFinder applies a **160-bit private key optimization**:

- The upper 96 bits of each 256-bit private key are set to zero  
- Only the lower 160 bits are randomized and traversed

This reduction in scalar size speeds up `k·G` computations, resulting in significantly better performance during brute-force and batch-based key scanning.

> ✅ Matches the size of `RIPEMD160(SHA256(pubkey))`  
> ✅ Especially effective when combined with OpenCL acceleration

### 🚀 Bloom Filter Address Cache (`useBloomFilter`)
As of version 1.5.0, a memory-efficient Bloom filter can be used to significantly accelerate address checks:

```json
"useBloomFilter": true
```

Instead of loading all addresses into a Java `HashSet`, a compact Bloom filter is loaded into RAM. This enables ultra-fast `containsAddress()` checks with minimal memory usage — even for millions or billions of entries.
Advantages:
- ✅ O(1) lookup speed (comparable to HashSet)
- ✅ Low memory usage, even with large datasets
- ✅ No false negatives (real matches are always detected)
- ⚠️ Possible false positives → only trigger additional LMDB lookups

#### Estimated Memory Usage:
| fpp    | Light Database (~132M) | Full Database (~1.37B)  |
|--------|------------------------|-------------------------|
| 0.1    | ~**80 MB**             | ~**800 MB**             |
| 0.05   | ~**100 MB**            | ~**1024 MB**            |
| 0.01   | ~**151 MB**            | ~**1574 MB**            |

#### 🔧 Tuning Accuracy with `bloomFilterFpp`
The expected false positive probability (FPP) can be configured:

```json
"bloomFilterFpp": 0.1
```

| Value | Description |
|-------|-------------|
| `0.01` | ✅ Only ~1% false positives – high accuracy, more memory |
| `0.05` | ⚖️ Balanced tradeoff between memory and performance |
| `0.1`–`0.2` | 🪶 Very memory-efficient – suitable if some false positives are acceptable |

```json
"useBloomFilter": true,
"bloomFilterFpp": 0.1
```
Recommended setting for best balance between speed and memory usage.

### 🔐 Public Key Hashing on GPU (SHA-256 + RIPEMD-160)
The OpenCL kernel performs **blazing fast public key hashing** directly on the GPU using:

- `SHA-256(pubkey.x || pubkey.y)` followed by  
- `RIPEMD-160(SHA-256(pubkey))`

This allows each GPU thread to independently generate full Bitcoin-style public key hashes (`hash160`) **without CPU involvement**.

Benefits:  
- No host-side post-processing needed  
- Fully parallelized and memory-efficient  
- Ideal for massive batch generation and filtering

> ✅ Output is already in hash160 format, ready for address comparison

## Address Database
The addresses are stored in a high-performance database: [LMDB](https://github.com/LMDB).
The database can be used to check whether a generated address has ever been used.

### Address Import Support

The importer supports reading multiple `.txt` or `.text` files, each containing one address per line in arbitrary order. Lines may vary in address type and format. Each line may also optionally include an associated coin amount.

⚠️ **Unsupported or malformed lines are silently skipped during import.**

#### Supported Address Types

* **P2PKH** – Pay to Public Key Hash
  Encoded using Base58. Most commonly used format for legacy Bitcoin addresses.

* **P2SH** – Pay to Script Hash
  Base58-encoded address type used for multisig and other script-based spending conditions.

* **P2WPKH** – Pay to Witness Public Key Hash
  Native SegWit v0 address, encoded in **Bech32**. One private key deterministically produces one address.

#### Unsupported Address Types

* **P2MS** – Pay to Multisig
  Custom format prefixed with `d-`, `m-`, or `s-` (e.g. `m-<script>`).
  ❌ **Not Supported:** Script-based format. Private keys cannot deterministically generate P2MS addresses without knowing the script.

* **P2WSH** – Pay to Witness Script Hash
  Native SegWit v0 address for scripts, encoded in **Bech32**.
  ❌ **Not Supported:** Script Hash format. Addresses depend on the script hash, not directly on the public key.

* **P2TR** – Pay to Taproot
  Native SegWit v1 (Taproot) address, encoded using **Bech32m**.
  ❌ **Not Supported:** Requires key tweaking based on an optional script. Without knowing the script, you cannot generate matching P2TR addresses from a private key. One private key can create infinite different P2TR addresses. This breaks the tool's design, which maps private keys to deterministic addresses.

> **Note on Witness Versions:**
> Bech32 was introduced in [BIP-173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) for SegWit v0 (P2WPKH, P2WSH).
> Bech32m, defined in [BIP-350](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki), is used for SegWit v1 (P2TR).

#### Special Formats

In addition to standard script types, the importer also recognizes and supports several special address encodings:

* **Bitcoin Cash (Base58 prefix `q`)**  
  Legacy Bitcoin Cash addresses using the `q`-prefix are automatically converted to legacy Bitcoin format.

* **BitCore WKH**  
  Custom format prefixed with `wkh_` and encoded in **Base36**.

* **Riecoin P2SH as ScriptPubKey**  
  Riecoin P2SH addresses are provided as raw ScriptPubKey hex (starting with `76a914...`).

---

> **Legend:**  
> ✅ = Supported and tested  
> ❌ = Explicitly not supported (format known but intentionally excluded)  
> _empty_ = Unknown or unverified — either not implemented by the altcoin project, or no valid address example was found (thus no implementation or test exists)

| Coin                                                                                     |  TAG  | P2PKH | P2SH | P2WPKH | P2WSH  |  P2MS  |  P2TR  |
|------------------------------------------------------------------------------------------|:-----:|:-----:|:----:|:------:|:------:|:------:|:------:|
| [42-coin](https://github.com/42-coin/42)                                                 | 42    |  ✅   | ✅   |        |        |        |       |
| [Alias](https://github.com/aliascash)                                                    | ALIAS |  ✅   |      |        |        |        |       |
| [Argoneum](https://github.com/Argoneum/argoneum)                                         | AGM   |  ✅   |      |        |        |        |       |
| [Artbyte](https://github.com/WikiMin3R/ArtBytE)                                          | ABY   |  ✅   |      |        |        |        |       |
| [Auroracoin](https://github.com/aurarad/Auroracoin)                                      | AUR   |  ✅   |      |        |        |        |       |
| [B3Coin](https://github.com/B3-Coin/B3-CoinV2)                                           | B3    |  ✅   |      |        |        |        |       |
| [BBQCoin](https://github.com/BBQCoinCommunity/BBQCoin)                                   | BQC   |  ✅   |      |        |        |        |       |
| [Bean Cash](https://github.com/teambean/BeanCash)                                        | BEAN  |  ✅   |      |        |        |        |       |
| [Biblepay](https://github.com/biblepay/biblepay)                                         | BBP   |  ✅   |      |        |        |        |       |
| [BitBay](https://github.com/bitbaymarket/bitbay-core)                                    | BAY   |  ✅   |      |        |        |        |       |
| [BitBlocks](https://github.com/BitBlocksProject/BitBlocks)                               | BBK   |  ✅   |      |        |        |        |       |
| [Bitcoin](https://github.com/bitcoin/bitcoin)                                            | BTC   |  ✅   | ✅   | ✅    | ❌     |  ❌    | ❌    |
| [Bitcoin Cash](https://github.com/bitcoincashbch/bitcoin-cash)                           | BCH   |  ✅   | ❌   |        |        |  ❌    |       |
| [Bitcoin Gold](https://github.com/btcgpu)                                                | BTG   |  ✅   |      |        |        |        |       |
| [Bitcoin Oil](https://github.com/escapeneo/bitcoinoil/)                                  | BTCO  |  ✅   |      | ✅     | ❌     |        |       |
| [Bitcoin Plus](https://github.com/bitcoinplusorg/xbcwalletsource)                        | XBC   |  ✅   |      |        |        |        |       |
| [BitCore](https://github.com/bitcore-btx/bitcore)                                        | BTX   |  ✅   |      | ✅     | ❌     |        |       |
| [Bitmark](https://github.com/project-bitmark/bitmark)                                    | BTMK  |  ✅   |      |        |        |        |       |
| [BlackCoin](https://gitlab.com/blackcoin/blackcoin-more)                                 | BLK   |  ✅   |      |        |        |        |       |
| [BlakeBitcoin](https://github.com/BlakeBitcoin/BlakeBitcoin)                             | BBTC  |  ✅   |      |        |        |        |       |
| [Blakecoin](https://github.com/BlueDragon747/Blakecoin)                                  | BLC   |  ✅   |      |        |        |        |       |
| [Blocknet](https://github.com/BlocknetDX/BlockDX)                                        | BLOCK |  ✅   |      |        |        |        |       |
| [BolivarCoin](https://github.com/BOLI-Project/BolivarCoin)                               | BOLI  |  ✅   |      |        |        |        |       |
| [BYTZ](https://github.com/bytzcurrency)                                                  | BYTZ  |  ✅   | ✅   |        |        |        |       |
| [Canada-eCoin](https://github.com/Canada-eCoin/eCoinCore)                                | CDN   |  ✅   |      | ✅     | ❌      |        |         |
| [Catcoin](https://github.com/CatcoinCore/catcoincore)                                    | CAT   |  ✅   |      |        |        |        |         |
| [ChessCoin 0.32%](https://github.com/AKKPP/ChessCoin032/)                                | CHESS |  ✅   |      |        |        |        |         |
| [Clam](https://github.com/nochowderforyou/clams)                                         | CLAM  |  ✅   |      |        |        |        |         |
| [CloakCoin](https://github.com/CloakProject/CloakCoin)                                   | CLOAK |  ✅   | ✅   |        |        |        |         |
| [C-Note](https://github.com/cnote-chain/CNOTE)                                           | CNOTE |  ✅   |     |        |        |        |         |
| [Coino](https://github.com/scriptRack003756/coino)                                       | CNO   |  ✅   |      |        |        |         |       |
| [ColossusXT](https://github.com/ColossusCoinXT/ColossusCoinXT)                           | COLX  |  ✅   |      |        |        |         |       |
| [Compound](https://github.com/compounddev/Compound-Coin)                                 | COMP |  ✅   |      |        |        |         |       |
| [CROWN](https://github.com/Crowndev/crowncoin)                                           | CRW   |  ✅   |      |        |        |         |       |
| [Cryptoshares](https://github.com/Cryptosharescoin/shares)                               | SHARES|  ✅   |      |        |        |         |       |
| [Curecoin](https://github.com/cygnusxi/CurecoinSource)                                   | CURE  |  ✅   |      |        |        |         |       |
| [Dash](https://github.com/dashpay/dash)                                                  | DASH  |  ✅   | ✅   |        |        |        |         |
| [Defcon](https://github.com/defcon-project/defcon)                                       | DEFCON|  ✅   | ✅   |        |         |        |         |
| [DeFiChain](https://github.com/DeFiCh/ain)                                               | DFI   |  ✅   | ✅   | ✅     | ❌      |        |         |
| [Deutsche eMark](https://github.com/emarkproject/eMark)                                  | DEM   |  ✅   |      |        |        |        |         |
| [Diamond](https://github.com/DMDcoin/Diamond)                                            | DMD   |  ✅   |      |        |        |        |         |
| [DiminutiveCoin](https://github.com/MadCatMining/DiminutiveCoin)                         | DIMI  |  ✅   |      |        |        |        |         |
| [DigiByte](https://github.com/digibyte-core/digibyte)                                    | DGB   |  ✅   |      | ✅     | ❌     |        |         |
| [DigitalCoin](https://github.com/lomtax/digitalcoin)                                     | DGC   |  ✅   |      |        |        |         |       |
| [Dimecoin](https://github.com/dime-coin/dimecoin)                                        | DIME  |  ✅   |      |        |        |         |       |
| [Divicoin](https://github.com/DiviProject/Divi)                                          | DIVI  |  ✅   |      |        |        |         |       |
| [Dogecoin](https://github.com/dogecoin/dogecoin)                                         | DOGE  |  ✅   | ✅   |        |        |        |         |
| [Dogmcoin](https://github.com/dogmcoin/dogmcoin)                                         | DOGM  |  ✅   |      |        |        |         |       |
| [Doichain](https://github.com/Doichain/doichain-core)                                    | DOI   |  ✅   |      | ✅     | ❌     |        |         |
| [e-Gulden](https://github.com/Electronic-Gulden-Foundation/egulden)                      | EFL   |  ✅   |      |        |        |         |       |
| [Electron](https://github.com/Electron-Coin2014/Electron-ELT)                            | ELT   |  ✅   |      |        |        |         |       |
| [Element (HYP)](https://github.com/Crypto-city/Element-HYP)                              | HYP   |  ✅   |      |        |        |         |       |
| [Elite](https://github.com/ironsniper1/Elite-Source-2.0.1.2)                             | 1337  |  ✅   |      |        |        |         |       |
| [Emerald](https://github.com/crypto-currency/Emerald)                                    | EMD   |  ✅   |      |        |        |         |       |
| [EverGreenCoin](https://github.com/EverGreenCoinDev/EverGreenCoin)                       | EGC   |  ✅   |      |        |        |         |       |
| [Feathercoin](https://github.com/FeatherCoin/Feathercoin)                                | FTC   |  ✅   |      | ✅     | ❌     |         |         |
| [Firo](https://github.com/firoorg/firo/)                                                 | FIRO  |  ✅   |      |        |       |         |         |
| [Freedomcoin](https://github.com/FreedomCoin-Project/FreedomCoin-Core/)                  | FREED |  ✅   |      |        |        |         |       |
| [GapCoin](https://github.com/gapcoin/gapcoin)                                            | GAP   |  ✅   |      |        |        |         |       |
| [Goldcash](https://github.com/iUNeIV/GoldCash)                                           | GOLD  |  ✅   |      |        |        |         |       |
| [GoldCoin](https://github.com/goldcoin/goldcoin)                                         | GLC   |  ✅   |      |        |        |         |       |
| [Groestlcoin](https://github.com/GroestlCoin/GroestlCoin/)                               | GRS   |  ✅   |      | ✅     | ❌     |         |       |
| [Hemis](https://github.com/Hemis-Blockchain/Hemis)                                       | HMS   |  ✅   |      |        |        |         |       |
| [Herencia](https://github.com/herenciacoin/HEIRS)                                        | HEIRS |  ✅   |      |        |        |         |       |
| [HoboNickels](https://github.com/Tranz5/HoboNickels)                                     | HBN   |  ✅   |      |        |        |         |       |
| [HTMLCOIN](https://github.com/HTMLCOIN)                                                  | HTML  |  ✅   |      |        |        |         |       |
| [I/O Coin](https://github.com/IOCoin/DIONS)                                              | IOC   |  ✅   |      |        |        |         |       |
| [IDChain](https://github.com/idchaincoin/idchaincoin)                                    | DCT   |  ✅   |      |        |        |         |       |
| [Innova](https://github.com/innova-foundation/innova)                                    | INN   |  ✅   |      |        |        |         |       |
| [InfiniLooP](https://github.com/WikiMin3R/InfiniLooP/)                                   | IL8P  |  ✅   |      |        |        |         |       |
| [Infinitecoin](https://github.com/infinitecoin-project/infinitecoin)                     | IFC   |  ✅   |      |        |        |         |       |
| [iXcoin](https://github.com/IXCore/IXCoin)                                               | IXC   |  ✅   |      |        |        |         |       |
| [Kobocoin](https://github.com/kobocoin/Kobocoin/)                                        | KOBO  |  ✅   |      |        |        |         |       |
| [Komodo](https://github.com/KomodoPlatform/komodo)                                       | KMD   |  ✅   |      |        |        |         |       |
| [Lanacoin](https://github.com/LanaCoin/lanacoin)                                         | LANA  |  ✅   |      |        |        |         |       |
| [Litecoin](https://github.com/litecoin-project/litecoin)                                 | LTC   |  ✅   | ✅   | ✅     | ❌     |        |         |
| [Litecoin Cash](https://github.com/litecoincash-project/litecoincash)                    | LCC   |  ✅   |      | ✅     | ❌     |         |         |
| [LiteDoge](https://github.com/ldoge/LDOGE)                                               | LDOGE |  ✅   |      |        |        |         |       |
| [Lithium](https://github.com/lithiumcoin/lithium)                                        | LIT   |  ✅   |      |        |        |         |       |
| [Luckycoin](https://github.com/LuckycoinFoundation/Luckycoin)                            | LKY   |  ✅   |      |        |        |         |       |
| [Lynx](https://github.com/getlynx/Lynx)                                                  | LYNX  |  ✅   |      |        |        |         |       |
| [MasterNoder2](https://github.com/jonK341/MasterNoder2)                                  | MN2   |  ✅   |      |        |        |         |       |
| [Mooncoin](https://github.com/%20mooncoincore/wallet/releases)                           | MOON  |  ✅   | ✅   | ✅     | ❌      |         |       |
| [MotaCoin](https://github.com/Jahvinci/MotaCoin)                                         | MOTA  |  ✅   |      |        |        |         |       |
| [Myriad](https://github.com/myriadteam/myriadcoin)                                       | XMY   |  ✅   | ✅   | ✅     | ❌     |        |         |
| [Namecoin](https://github.com/namecoin/namecoin-core)                                    | NMC   |  ✅   |      | ✅     | ❌     |         |         |
| [NewYorkCoin](https://github.com/NewYorkCoinNYC)                                         | NYC   |  ✅   |      |        |        |         |       |
| [Novacoin](https://github.com/novacoin-project/novacoin)                                 | NVC   |  ✅   |      |        |        |         |       |
| [Oduwacoin](https://github.com/ODUWAX/oduwacoin)                                         | OWC   |  ✅   |      |        |        |         |       |
| [PAC Protocol](https://github.com/pacprotocol/pacprotocol)                               | PAC   |  ✅   |      |        |        |         |       |
| [PakCoin](https://github.com/Pakcoin-project/pakcoin)                                    | PAK   |  ✅   |      |        |        |         |       |
| [PandaCoin](https://github.com/DigitalPandacoin/pandacoin)                               | PND   |  ✅   |      |        |        |         |       |
| [Particl](https://github.com/particl/particl-core)                                       | PART  |  ✅   | ✅   |        |        |         |       |
| [PeepCoin](https://github.com/PXN-Foundation/Peepcoin/)                                  | PCN   |  ✅   |      |        |        |         |       |
| [Peercoin](https://github.com/peercoin/peercoin)                                         | PPC   |  ✅   |      |        |        |         |       |
| [Photon](https://github.com/photonproject/photon)                                        | PHO   |  ✅   |      |        |        |         |       |
| [Pinkcoin](https://github.com/Pink2Dev/Pink2)                                            | PINK  |  ✅   |      |        |        |         |       |
| [PIVX](https://github.com/PIVX-Project/PIVX/)                                            | PIVX  |  ✅   |      |        |        |         |       |
| [PotCoin](https://github.com/potcoin/potcoin)                                            | POT   |  ✅   |      |        |        |         |       |
| [Primecoin](https://github.com/primecoin/primecoin)                                      | XPM   |  ✅   |      |        |        |         |       |
| [PutinCoin v2](https://github.com/PutinCoinPUT/PutinCoin)                                | PUT   |  ✅   |      |        |        |         |       |
| [Quark](https://github.com/quark-project-evolution/quark/)                               | QRK   |  ✅   |      |        |        |         |       |
| [Raptoreum Core](https://github.com/Raptor3um/raptoreum)                                 | RTM   |  ✅   |      |        |        |        |         |
| [Reddcoin](https://github.com/reddcoin-project/reddcoin)                                 | RDD   |  ✅   |      |        |        |        |         |
| [Riecoin](https://github.com/riecointeam/riecoin)                                        | RIC   |       | ✅   | ✅     | ❌    |         |       |
| [SaluS](https://github.com/saluscoin/salus)                                              | SLS   |  ✅   | ✅   |        |        |         |       |
| [SexCoin](https://github.com/sexcoin-project/sexcoin)                                    | SXC   |  ✅   |      |        |        |         |       |
| [Slimcoin](https://github.com/slimcoin-project/Slimcoin)                                 | SLM   |  ✅   |      |        |        |         |       |
| [Smileycoin](https://github.com/tutor-web/smileyCoin)                                    | SMLY  |  ✅   |      |        |        |         |       |
| [Smoke](https://github.com/cannacoin-official/cannacoin-smoke)                           | SMOKE |  ✅   |      |        |        |         |       |
| [SpaceXpanse](https://github.com/SpaceXpanse/rod-core-wallet)                            | ROD   |  ✅   |      | ✅     | ❌     |         |       |
| [Sparks](https://github.com/sparkspay/sparks/)                                           | SPK   |  ✅   |      |        |        |         |       |
| [Stakecoin](https://github.com/sleewis/stakecoin)                                        | STK   |  ✅   |      |        |        |         |       |
| [Sterlingcoin](https://github.com/Sterlingcoin/Sterlingcoin-1.6.2.0-Release)             | SLG   |  ✅   |      |        |        |         |       |
| [Stronghands](https://bitbucket.org/bumbacoin/stronghands-new)                           | SHND  |  ✅   |      |        |        |         |       |
| [Syscoin](https://github.com/syscoin/syscoin)                                            | SYS   |  ✅   |      | ✅     | ❌     |         |       |
| [TajCoin](https://github.com/Taj-Coin/tajcoin)                                           | TAJ   |  ✅   |      |        |        |         |       |
| [Terracoin](https://github.com/terracoin/terracoin)                                      | TRC   |  ✅   |      |        |        |         |       |
| [TheHolyRogerCoin](https://github.com/TheHolyRoger/TheHolyRogerCoin)                     | ROGER |  ✅   |      | ✅     | ❌     |         |       |
| [Trezarcoin](https://github.com/TrezarCoin/TrezarCoin)                                   | TZC   |  ✅   |      |        |        |         |       |
| [Trollcoin](https://github.com/TrollCoin2/TrollCoin-2.0)                                 | TROLL |  ✅   |      |        |        |         |       |
| [UFO](https://github.com/fiscalobject/ufo)                                               | UFO   |  ✅   | ✅   | ✅     | ❌      |        |         |
| [UFOhub](https://github.com/MyGCoin/UFOHub-Coin)                                         | UFOHUB|  ✅   |      |        |        |         |       |
| [Unitus](https://github.com/unitusdev/unitus)                                            | UIS   |  ✅   |      |        |        |         |       |
| [UniversalMolecule](https://github.com/universalmol/universalmol)                        | UMO   |  ✅   |      |        |        |         |       |
| [Unobtanium](https://github.com/unobtanium-official/Unobtanium)                          | UNO   |  ✅   |      |        |        |        |         |
| [Validity](https://github.com/RadiumCore/Validity)                                       | VAL   |  ✅   |      |        |        |         |       |
| [Vanillacash](https://github.com/WikiMin3R/Vanillacash)                                  | XVC   |  ✅   |      |        |        |         |       |
| [VeriCoin](https://github.com/vericoin/vericoin)                                         | VRC   |  ✅   |      |        |        |         |       |
| [Versacoin](https://github.com/versacoin/versacoin)                                      | VCN   |  ✅   |      |        |        |         |       |
| [Vertcoin](https://github.com/vertcoin/vertcoin)                                         | VTC   |  ✅   |      | ✅     | ❌     |         |       |
| [VirtaCoin](https://github.com/virtacoin/VirtaCoinProject)                               | VTA   |  ✅   |      |        |        |         |       |
| [VirtacoinPlus](https://github.com/virtacoinplus/virtacoinplus)                          | XVP   |  ✅   |      |        |        |         |       |
| [WorldCoin](https://github.com/OfficialWorldcoinGlobal/Worldcoin)                        | WDC   |  ✅   |      |        |        |         |       |
| [Zetacoin](https://github.com/WikiMin3R/ZetacoinE)                                       | ZET   |  ✅   |      |        |        |         |       |
| [ZCash](https://github.com/zcash/zcash)                                                  | ZEC   |  ✅   | ✅   |        |        |        |         |

### Create the database by yourself
Useful txt/text file provider:
* http://blockdata.loyce.club/alladdresses/
* https://blockchair.com/dumps


### Export
The exporter provides various output formats for Bitcoin and altcoin address data:

* **HexHash**  
  Exports addresses as raw `hash160` (RIPEMD-160 of the SHA-256 of the public key), encoded in hexadecimal. No version byte or checksum is included. Ideal for advanced usage and low-level comparison. Best viewed in fixed-width hex viewers (e.g., HxD).

* **FixedWidthBase58BitcoinAddress**  
  Exports Base58Check-encoded addresses (e.g., legacy `P2PKH`) in a fixed-width format for consistent alignment. No amount is included. Suitable for hex/byte-aligned visual inspection and batch comparison.

* **DynamicWidthBase58BitcoinAddressWithAmount**  
  Exports Base58Check-encoded addresses along with their associated amounts (e.g., balance or UTXO value), using a dynamic-width format. Suitable for human-readable CSV-like formats and analytics.

---

### Use My Prepared Database
I am in the process of building and publishing databases containing large sets of Bitcoin and altcoin addresses.  
(Refer to the **Import** section above for details on supported address formats.)

> The sources of these addresses are confidential, but you are fully permitted to extract, inspect, and use them.

You are also welcome to **extend this database** by importing your own address data. This allows you to build upon the existing dataset, tailoring it to your specific needs (e.g., adding additional coins, formats, or private address collections).

If you're missing any information or have questions about usage or content, feel free to ask or open an issue.

#### Light database
* Light (5.4 GiB), Last update: July 1, 2025
  * Contains Bitcoin addresses whith amount and many altcoin addresses with amount.
  * Static amount of 0 is used to allow best compression.
  * Unique entries: 132288304
  * Mapsize: 5576 MiB
  * Time to create the database: ~9 hours
  * Link (3.66 GiB zip archive): http://ladenthin.net/lmdb_light.zip
  * Link extracted addresses as txt (5.17 GiB) (2.29 GiB zip archive); open with HxD, set 42 bytes each line: http://ladenthin.net/LMDBToAddressFile_Light_HexHash.zip

> 💡 **Hint:** When using the light database, it is **strongly recommended** to enable the following setting in your configuration:
> ```json
> "loadToMemoryCacheOnInit" : true
> ```  
> Although LMDB is very fast, a Java `HashSet` provides true **O(1)** lookups compared to **O(log n)** (or worse) with disk-backed access.
> Enabling this flag loads all addresses into memory at startup, resulting in significantly higher throughput during key scanning — especially for OpenCL or high-frequency batch operations.

<details>
<summary>Checksums lmdb_light.zip</summary>

```txt
lmdb_light.zip	CRC32	DF77E5CF
lmdb_light.zip	MD5	4B733EAFF200C8044F80BE68538BB164
lmdb_light.zip	RipeMD160	A82C31F511C9BF3CDCA705E63860B5B597227EB3
lmdb_light.zip	SHA-1	C2E9FA56578C9F73942943C7861B226C6B44AC18
lmdb_light.zip	SHA-256	3B8AB59232D9CBB67118A79143E788E0B08A957E9C3D877F8B41303005170DC0
lmdb_light.zip	SHA-512	108D88E7EE1E90BEE975ADB711438C41971B23A65751EFB33EA6287A9697DC563ECCE40452DFA2DD1E0F66637F5AA14CC02D9A621AED953E0DA6FCEDD9D9C440
lmdb_light.zip	SHA3-224	BDF86A26D072BF521AE4A909AC912AC1C0F4EEAB33D12AE4D554327F
lmdb_light.zip	SHA3-256	55206B88314AD7F2907740FBD49C462BC0B1C2F075C23807E71E095EE9712345
lmdb_light.zip	SHA3-384	D23681FC1722253F2B51BBCF9CDA22FDD2B79C33657D38C938B64392E8CD4957AAD1FD4E6D54E7B9FF1A98C3D110C52F
lmdb_light.zip	SHA3-512	096B12FE4CB1A095287F678C10B30418091FCBF1FABB77003969C6D9846F1344A0C8918B3D2D047E94363B6E9BC5324801EA0E14331A012E8123FDE44672B394
```

</details>

<details>
<summary>Checksums LMDBToAddressFile_Light_HexHash.zip</summary>

```txt
LMDBToAddressFile_Light_HexHash.zip	CRC32	AA42A096
LMDBToAddressFile_Light_HexHash.zip	MD5	EB2E19F7AFE545A1A98FAE134D5394D4
LMDBToAddressFile_Light_HexHash.zip	RipeMD160	A011232D5069884ACFBE76C8DF4069DF684768DB
LMDBToAddressFile_Light_HexHash.zip	SHA-1	C8899544133C605EAB9FE2C83227854737B8D3FC
LMDBToAddressFile_Light_HexHash.zip	SHA-256	A8B67B606C574A4F895FA7E9B5E0AA9830C5DDD7E615EB59D77C2324E388DB78
LMDBToAddressFile_Light_HexHash.zip	SHA-512	4FD1B0905016292169A23E166C0D1C4D448DADFE4EC8FE410C1991D37B6AB5FE34596FD6EDFC62C0DE8EC8AD7142212F105ACD137B9A71F5F71E1BB1FB3B9278
LMDBToAddressFile_Light_HexHash.zip	SHA3-224	858550C2805FF1A20F3728392E70CAB9E4952792F31FA0881B0031D2
LMDBToAddressFile_Light_HexHash.zip	SHA3-256	4B522E2F4225D6FB238228033CC8AAE843DC24BA00B32BCBCA0D23B9A4C1AC46
LMDBToAddressFile_Light_HexHash.zip	SHA3-384	C29158FCB83F2D4F25BC610CE4D143964AC984ACA9D2064C9B8D40F33679830B3704A99BF408DAC75702658E55F58A7D
LMDBToAddressFile_Light_HexHash.zip	SHA3-512	29CA44CD666D7B8CF9EAD4B340620FBB7EDC30F47DBC2582A57E3DFF5E537A2A2F2CE7A7CEC2C6EF21775F7B839E0D1F23BE720CE0FC64F304B142AFAFA1437E
```

</details>


#### Full database
* Full (57.0 GiB), Last update: June 4, 2025
  * Contains all Bitcoin addresses which are ever used and many altcoin addresses with and without amount.
  * Static amount of 0 is used to allow best compression.
  * Unique entries: 1377481459
  * Mapsize: 58368 MiB
  * Time to create the database: ~54 hours
  * Link (34.3 GiB zip archive): http://ladenthin.net/lmdb_full.zip
  * Link extracted addresses as txt (23.4 GiB zip archive); open with HxD, set 42 bytes each line: http://ladenthin.net/LMDBToAddressFile_Full_HexHash.zip

<details>
<summary>Checksums lmdb_full.zip</summary>

```txt
lmdb_full.zip	CRC32	815A7A2D
lmdb_full.zip	MD5	AF29E5E75C62DC9591DFE0C101726296
lmdb_full.zip	RipeMD160	6137C2A7BDA337C274141ED866C7C9B5F011A47E
lmdb_full.zip	SHA-1	82554DD5C17BBDCD071015382AF4E1A8F3A85B33
lmdb_full.zip	SHA-256	DD9F6ACE080D24D80C1C032361226348D62CAF8BD0C0C09E0473A76F1ED95D57
lmdb_full.zip	SHA-512	0DF89EDB8243A4E12F56BC1AB9DF2C558A32FE14919B8A648CD3EB6869611DE035B044DEFAE6A5D5835886CBA405975E534BE4A624CD17A39CF69CF45A46381A
lmdb_full.zip	SHA3-224	43FF7478841483F022866569B73D89C7A4D154564CBE343873C29C61
lmdb_full.zip	SHA3-256	EB02EA6321F346406011F8195A57AA43BDAFAD2BBD34944ED27A87EF04FC509D
lmdb_full.zip	SHA3-384	F1A91448D85A84E6059EDED27E23FE5939B5F2A9BCE5DC260C8CAEF7B2E5AAFF75F6FE58AFB05F13094441F91DF3B031
lmdb_full.zip	SHA3-512	EF669BAD483E373CE4AFBA37AAE800A030F78E3D81972D8385E659DC5BEF2973E279D8666F53F727F1891F2C242896A957944E2E8E24BF138BC61C5A58394A7A
```

</details>

<details>
<summary>Checksums LMDBToAddressFile_Full_HexHash.zip</summary>

```txt
LMDBToAddressFile_Full_HexHash.zip	CRC32	41E4AF53
LMDBToAddressFile_Full_HexHash.zip	MD5	920B9656E21A0B68737255FC240F48D2
LMDBToAddressFile_Full_HexHash.zip	RipeMD160	73689B50945034554DADA23E5C25B49FCD1BF57C
LMDBToAddressFile_Full_HexHash.zip	SHA-1	2C59FCBF6FB53EDEB9E3B9069E67A547F114AEC6
LMDBToAddressFile_Full_HexHash.zip	SHA-256	CC45F6E8F383344D918B9C9F2AEDA5846211D878B7E05E222DB066106230BFBE
LMDBToAddressFile_Full_HexHash.zip	SHA-512	18E1739A6380D421F232C669DBD685B418B6F2D462C92E711539D2A2EEC606CEEDF58E19014B23A8936093ED07D55F51CFDC374B59B3299332E0DED223A53A96
LMDBToAddressFile_Full_HexHash.zip	SHA3-224	24B2D4AD34E73B59FB7BA5F8E064288176733A2634B5470B25B1C0DE
LMDBToAddressFile_Full_HexHash.zip	SHA3-256	1CC79E2F24031A37BFB5FFEA27C07CC654CDD91224A334F52095AF16FBE81F55
LMDBToAddressFile_Full_HexHash.zip	SHA3-384	CA115D352C2609B0B2E85010CC13175E7DC3C8F6295B3B6B4BD858D60D81D6E3EA706E4979F764A4C6BF7D351153A429
LMDBToAddressFile_Full_HexHash.zip	SHA3-512	A1419AFFE869B18973D499439E7EA90A94C4C7C6818F719741E59DD619985C6867F6C51F31BC7EDEBF27356D11B013E4D36FB83D89E5FFB1F77566FF5582FBD5
```

</details>

---

## Pages and projects to get lists (dumps) of PubkeyHash addresses
* https://github.com/Pymmdrza/Rich-Address-Wallet
* https://github.com/mycroft/chainstate
* https://github.com/graymauser/btcposbal2csv
* https://blockchair.com/dumps
* https://balances.crypto-nerdz.org/

## Find Addresses
### 🔢 Key Generation Configuration  
BitcoinAddressFinder supports multiple pseudorandom number generators (PRNGs) for private-key creation.
Pick one in your JSON via the `keyProducerJavaRandomInstance` field, e.g. `"keyProducerJavaRandomInstance": "SECURE_RANDOM"`.
This flexibility lets you switch between **production-grade entropy** and **deterministic or deliberately weak sources** for audits and research.

#### Key producer Use Cases
* 🔐 Secure wallet generation
* 🧪 Testing deterministic output
* 🕵️ Simulating vulnerabilities
* 🔄 Reproducible scans

> ⚠️ **Security Warning**: This software is intended for research and educational purposes. Do **not** use it in production or on systems connected to the internet.

A secure environment should be fully isolated — ideally an air-gapped computer (physically disconnected from all networks).  
The software is highly optimized for performance and **not designed to run in constant time**, which means it may be vulnerable to **side-channel attacks** on shared or exposed systems.

For generated vanity addresses or private keys, consider storing them safely using a [paper wallet](https://en.bitcoin.it/wiki/Paper_wallet).

#### Supported PRNG Modes (key producer java random)

| Value | Description |
|-------|-------------|
| `SECURE_RANDOM` | ✅ Cryptographically secure system CSPRNG (`/dev/urandom`, Windows CNG). **Recommended for real wallet generation.** |
| `RANDOM_CURRENT_TIME_MILLIS_SEED` | ⚠️ `java.util.Random` seeded with the current timestamp. **Insecure**; handy for replaying time-window RNG flaws. |
| `RANDOM_CUSTOM_SEED` | ⚠️ `java.util.Random` with user-supplied seed. Fully deterministic; useful for reproducible fuzzing or fixed keyspaces. |
| `SHA1_PRNG` | ⚠️ Legacy “SHA1PRNG” engine (Android pre-2013). Lets you reproduce the historic SecureRandom bug. |

#### Examples
##### 🔐 `SECURE_RANDOM`  
Best choice for real wallet generation – uses system CSPRNG (e.g. `/dev/urandom`, Windows CNG).
```json
...
"keyProducerJavaRandom": [
  {
    "keyProducerId": "exampleKeyProducerId",
    "keyProducerJavaRandomInstance": "SECURE_RANDOM"
  }
],
...
```

##### 🕰️ `RANDOM_CURRENT_TIME_MILLIS_SEED`  
Recreates time-based vulnerabilities using `java.util.Random` seeded with the current system time.
```json
...
"keyProducerJavaRandom": [
  {
    "keyProducerId": "exampleKeyProducerId",
    "keyProducerJavaRandomInstance": "RANDOM_CURRENT_TIME_MILLIS_SEED"
  }
],
...
```

##### 🧪 `RANDOM_CUSTOM_SEED`
Fully deterministic PRNG using `java.util.Random` with a user-defined seed. Useful for reproducible scans and testing.

Fully deterministic output. Useful for reproducible tests or fixed keyspace scans.
Without explicit seed:
```json
...
"keyProducerJavaRandom": [
  {
    "keyProducerId": "exampleKeyProducerId",
    "keyProducerJavaRandomInstance": "RANDOM_CUSTOM_SEED"
  }
],
...
```

With custom deterministic seed:
```json
...
"keyProducerJavaRandom": [
  {
    "keyProducerId": "exampleKeyProducerId",
    "keyProducerJavaRandomInstance": "RANDOM_CUSTOM_SEED",
    "customSeed": 123456789
  }
],
...
```

##### ⚠️ `SHA1_PRNG`
Legacy deterministic PRNG using `"SHA1PRNG"`. Used to reproduce the 2013 Android SecureRandom vulnerability. Can be used with or without an explicit seed.

Simulates old Android bug. May produce the same keys if seeded poorly or not at all.
Without seed:
```json
...
"keyProducerJavaRandom": [
  {
    "keyProducerId": "exampleKeyProducerId",
    "keyProducerJavaRandomInstance": "SHA1_PRNG"
  }
],
...
```

With custom seed:
```json
...
"keyProducerJavaRandom": [
  {
    "keyProducerId": "exampleKeyProducerId",
    "keyProducerJavaRandomInstance": "SHA1_PRNG",
    "customSeed": 987654321
  }
],
...
```

#### 🔐 `BIP39_SEED` (key producer java bip 39)
HD-wallet-style derivation: mnemonic + passphrase → BIP32/BIP44 keys.

Hierarchical deterministic key generator using a BIP39 mnemonic and optional passphrase. Allows full BIP32/BIP44 path derivation and reproducible HD wallets.

| JSON field | Type | Default | Purpose |
|------------|------|---------|---------|
| `mnemonic` | string | — | 12/24-word BIP39 sentence |
| `passphrase` | string | `""` | Optional BIP39 salt (“wallet password”) |
| `hardened` | boolean | `false` | 	Whether to use hardened key derivation (adds 0x80000000 to indices) |
| `bip32Path` | string | `"M/44H/0H/0H/0"` (constant `DEFAULT_BIP32_PATH`) | Base derivation path; must start with `M/` |
| `creationTimeSeconds` | number | `0` | Epoch-seconds creation timestamp; fed to `DeterministicSeed.ofMnemonic` |

Minimal:
```json
...
"keyProducerJavaBip39": [
    {
      "keyProducerId": "exampleKeyProducerId",
      "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
    }
],
...
```

Full:
```json
...
"keyProducerJavaBip39": [
    {
      "keyProducerId": "exampleKeyProducerId",
      "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
      "passphrase": "correct horse battery staple",
      "hardened" : false,
      "bip32Path": "M/44H/0H/0H/0",
      "creationTimeSeconds": 1650000000
    }
],
...
```

#### 🔢 incremental scanning (key producer java incremental)
This mode generates private keys **sequentially in batches** within a specified key range. It is especially useful for:

- **Systematic scanning** of a defined keyspace range (e.g., for key recovery or cryptographic research)
- **Batch processing** optimized for GPU/OpenCL parallelization
- Ensuring **deterministic and reproducible key generation** from start to end

---

#### Configuration Fields
| JSON field     | Type   | Default                                                                                    | Purpose                                                      |
|----------------|--------|--------------------------------------------------------------------------------------------|--------------------------------------------------------------|
| `startAddress` | string | `0000000000000000000000000000000000000000000000000000000000000002`                         | Hex string of the first private key in the range (inclusive) |
| `endAddress`   | string | `FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141` (secp256k1 group order) | Hex string of the last private key in the range (inclusive)  |

#### How it works
- Scanning begins **at `startAddress`**, producing sequential private keys in batches of size `batchSize`, up to and including `endAddress`.
- Each batch contains exactly `batchSize` keys.
- If the next full batch would go **beyond `endAddress`**, the process stops with an **exception**.
- The **`endAddress` is inclusive**, but **partial batches are not allowed by default** — batches must fit completely inside the range.
- For optimal performance, especially with OpenCL, configure `batchSize` and your GPU's grid size so that batches align perfectly within the range. This prevents errors and maximizes throughput.

> **Note:** If unsure, set the `endAddress` slightly higher to closely match the batch size. This helps avoid exceptions and ensures efficient scanning.

---

#### Example JSON Configuration
Example minimal configuration:

```json
...
{
  "keyProducerJavaIncremental": [
    {
      "keyProducerId": "exampleKeyProducerId",
      "startAddress": "0000000000000000000000000000000000000000000000000000000000000002",
      "endAddress": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
    }
  ]
}
...
```

🧩 This configuration incrementally searches a defined range of private keys. It is particularly suited for brute-force challenges, such as the [71st Bitcoin puzzle transaction](https://privatekeys.pw/puzzles/bitcoin-puzzle-tx?status=unsolved#p71).  
The private key range is specified by two 64-character hex strings: `startAddress` and `endAddress`.

```json
...
"keyProducerJavaIncremental": [
    {
      "keyProducerId": "exampleKeyProducerJavaIncremental",
      "startAddress": "0000000000000000000000000000000000000000000000400000000000000000",
      "endAddress":   "00000000000000000000000000000000000000000000007fffffffffffffffff"
    }
],
...
```

#### 🌐 `SOCKET_STREAM` (key producer java socket)  
Read raw private keys from a TCP socket stream (client or server mode).  
Useful for piping externally generated secrets (e.g., from Python, Go, etc.) directly into the finder.

| JSON Field                    | Type                             | Default       | Description                                                                         |
|-------------------------------|----------------------------------|---------------|-------------------------------------------------------------------------------------|
| `keyProducerId`               | string                           | —             | Unique identifier for this key producer                                             |
| `mode`                        | string enum (`CLIENT`, `SERVER`) | `"SERVER"`    | Whether to connect to a remote socket (`CLIENT`) or wait for connections (`SERVER`) |
| `host`                        | string                           | `"localhost"` | Remote host to connect to (used only in `CLIENT` mode)                              |
| `port`                        | number                           | `12345`       | TCP port to connect to or bind on                                                   |
| `timeout`                     | number                           | `3000`        | Socket read timeout in milliseconds                                                 |
| `logReceivedSecret`           | boolean                          | `false`       | Whether to log each received private key as a hex string                            |
| `connectionRetryCount`        | number                           | `5`           | Number of times to retry establishing a socket connection                           |
| `retryDelayMillisConnect`     | number                           | `1000`        | Delay between connection retry attempts (in milliseconds)                           |
| `readRetryCount`              | number                           | `3`           | Number of attempts to retry reading a full secret after I/O failure                 |
| `retryDelayMillisRead`        | number                           | `1000`        | Delay between read retry attempts (in milliseconds)                                 |
| `readPartialRetryCount`       | number                           | `5`           | Number of retries when partially reading a single 32-byte secret                    |
| `readPartialRetryDelayMillis` | number                           | `20`          | Delay between partial read retries (in milliseconds)                                |
| `maxWorkSize`                 | number                           | `16777216`    | Maximum number of secrets to request in a single call                               |


Minimal:
```json
...
"keyProducerJavaSocket": [
    {
        "keyProducerId": "exampleKeyProducerId",
        "host": "localhost",
        "port": 12345,
        "mode": "SERVER"
    }
],
...
```

Full:
```json
...
"keyProducerJavaSocket": [
    {
        "keyProducerId": "exampleKeyProducerId",
        "host": "localhost",
        "port": 12345,
        "mode": "SERVER",
        "timeout": 3000,
        "logReceivedSecret": true,
        "connectionRetryCount": 5,
        "retryDelayMillisConnect": 1000,
        "readRetryCount": 5,
        "retryDelayMillisRead": 1000,
        "readPartialRetryCount": 5,
        "readPartialRetryDelayMillis": 20,
        "maxWorkSize": 16777216
    }
],
...
```

##### Example: Python Socket Stream Server:
```python
import socket
import os
import time
import binascii

HOST = 'localhost'
PORT = 12345

while True:
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.connect((HOST, PORT))
            print(f"Connected to {HOST}:{PORT}")
            while True:
                private_key = os.urandom(32)
                print("Sending key:", binascii.hexlify(private_key).decode())
                s.sendall(private_key)
                time.sleep(1.0) # Slight delay to avoid flooding
    except ConnectionRefusedError:
        print("Connection refused, retrying in 1 second...")
        time.sleep(1)
    except BrokenPipeError:
        print("Connection lost, reconnecting...")
        time.sleep(1)
```

##### 🔄 Protocol
* Each private key must be exactly 32 raw bytes, sent binary, with no delimiter or framing.
* Keys are interpreted as big-endian (new BigInteger(1, bytes) in Java).
* Sending fewer than 32 bytes will cause blocking or exceptions.

#### 🌐 `SOCKET_STREAM` (key producer via ZeroMQ)
Receive raw private keys via a ZeroMQ `PULL` socket.
Ideal for decoupled key streaming where producers push keys using ZeroMQ `PUSH` sockets.

| JSON field         | Type                         | Default                | Description                                 |
|--------------------|------------------------------|------------------------|---------------------------------------------|
| keyProducerId      | string                       | —                      | Unique identifier for this key producer     |
| address            | string                       | tcp://localhost:5555   | The ZeroMQ address to bind or connect to    |
| mode               | string enum (BIND, CONNECT)  | BIND                   | Whether this socket binds to or connects    |
| timeout            | number                       | `-1`                   | Receive timeout in milliseconds:<br> `0` = non-blocking,<br> `-1` = infinite,<br> `>0` = wait that long |
| logReceivedSecret  | boolean                      | false                  | Whether to log each received secret in hex  |

Minimal:
```json
...
"keyProducerJavaZmq": [
    {
        "keyProducerId": "exampleKeyProducerId",
        "address": "tcp://localhost:5555"
    }
],
...
```

Full:
```json
...
"keyProducerJavaZmq": [
    {
        "keyProducerId": "exampleKeyProducerId",
        "address": "tcp://localhost:5555",
        "mode": "BIND",
        "timeout": -1,
        "logReceivedSecret": true
    }
],
...
```


##### Example: Python Socket Stream Server:
```python
import zmq
import os
import time
import binascii
from enum import Enum

class Mode(Enum):
    CONNECT = "connect"
    BIND = "bind"

ADDRESS = "tcp://localhost:5555"
MODE = Mode.CONNECT  # Change to Mode.BIND to switch

context = zmq.Context()

while True:
    try:
        socket = context.socket(zmq.PUSH)
        socket.setsockopt(zmq.SNDHWM, 1) # Limit send queue to 1 message

        if MODE == Mode.BIND:
            socket.bind(ADDRESS)
            print(f"Bound to {ADDRESS}")
        else:
            socket.connect(ADDRESS)
            print(f"Connected to {ADDRESS}")

        while True:
            private_key = os.urandom(32)
            print("Sending key:", binascii.hexlify(private_key).decode())
            try:
                socket.send(private_key, flags=zmq.NOBLOCK)
            except zmq.Again:
                print("Send queue full, message not sent.")
            time.sleep(1.0) # Slight delay to avoid flooding

    except zmq.ZMQError as e:
        print(f"ZMQ error occurred: {e}, retrying in 1 second...")
        time.sleep(1)

    finally:
        try:
            socket.close()
        except:
            pass
```

##### 🔄 Protocol
* Each private key must be exactly 32 raw bytes, sent as a single ZeroMQ message.
* Messages are interpreted as unsigned big-endian (`new BigInteger(1, bytes)` in Java).
* No framing or delimiters needed—ZeroMQ handles message boundaries.
* Messages larger or smaller than 32 bytes will be discarded or raise errors.


### Mixed Modes
You can combine **vanity address generation** with **database lookups** to enhance functionality and efficiency.

For example:
- Search for personalized (vanity) addresses using custom patterns **and**
- Simultaneously check if the generated addresses already **exist in the LMDB** database

This hybrid mode allows you to find rare or meaningful addresses while ensuring they haven’t been used before.

### Key Range

You can define a custom key range for private key generation—for example, limiting the search space to 64-bit keys.  
In this setup, the first 192 bits (256-bit - 64-bit) of the key are zeroed, effectively restricting the generation to a specific portion of the keyspace.

This feature can be used for:

- **Targeted key recovery**, such as searching for private keys from known ranges like the [Bitcoin Puzzle Transaction](https://privatekeys.pw/puzzles/bitcoin-puzzle-tx)
- **Verification and testing**, to prove that the software functions correctly within a predictable key range

### OpenCL Acceleration

To significantly boost the performance of EC key generation, the software supports OpenCL-based parallelization.

A shared secret (base key) is transferred to the OpenCL device along with a predefined grid size. Each OpenCL thread independently derives a unique EC key by incrementing the base key with its thread ID. This allows the generation of a batch of EC keys in a single execution cycle. Once generated, the keys are transferred back to the host (CPU) memory for further processing.

The CPU then hashes the X and Y coordinates of the public keys to derive the corresponding (Bitcoin/Altcoin) addresses. This division of labor offloads the computationally expensive elliptic curve operations to the GPU, allowing the CPU to focus on faster address hashing and database lookup operations—resulting in improved overall throughput.

#### Built-in Self-Test (BIST)

The OpenCL backend includes a built-in self-test mechanism that cross-verifies results from the GPU against a CPU-generated reference. This ensures that the OpenCL device is functioning correctly and producing valid EC keys—giving end users confidence in the reliability of their hardware-accelerated address search.
> 💡 **Hint:** To enable the built-in self-test, make sure the following configuration flag is set to `true`:  
> ```json
> "runtimePublicKeyCalculationCheck": true
> ```  
> This option is disabled by default. Enabling it is especially useful during development, debugging, or when validating new hardware setups.

#### ⚠️ BIP-39 Deterministic Keys and Batch Mode Limitation

If you configure a **BIP-39 key producer** (e.g. `keyProducerJavaBip39`) together with OpenCL acceleration, please read this carefully.

The BIP-39 key producer creates **deterministic private keys** derived from your mnemonic, passphrase, and BIP32 path.  
This derivation space is **finite** — once all child keys along the defined path are exhausted, the producer will throw  
a `NoMoreSecretsAvailableException`. This can happen relatively quickly in GPU batch configurations.

In your JSON configuration, you may have enabled:

```java
/**
 * The batch mode will use a private key increment internal to increase the performance.
 */
public boolean batchUsePrivateKeyIncrement = true;
```

When `batchUsePrivateKeyIncrement` is set to `true`, the OpenCL producer calls:

```java
secrets = keyProducer.createSecrets(cProducer.getOverallWorkSize(bitHelper), cProducer.batchUsePrivateKeyIncrement);
```

Internally this sets `returnStartSecretOnly = true`, meaning that **only the first BIP-39-derived key** is passed to the GPU.  
The OpenCL kernel then uses that single key as a **base key**, incrementing the **least significant bits (LSB)** in parallel across all GPU threads to explore adjacent keyspaces.

> ⚠️ **Use extreme caution:**  
> - The effective search space on the GPU is *not* the same as the full BIP-39 derivation sequence.  
> - This mode is intended purely for experimental or high-performance batch testing — not for full HD-wallet traversal.  
> - Once all deterministic child keys are consumed, a `NoMoreSecretsAvailableException` will occur.

For technical details, see:
- [`KeyProducerJavaBip39.java`](https://github.com/bernardladenthin/BitcoinAddressFinder/blob/main/src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaBip39.java)
- [`BIP39KeyProducer.java`](https://github.com/bernardladenthin/BitcoinAddressFinder/blob/main/src/main/java/net/ladenthin/bitcoinaddressfinder/BIP39KeyProducer.java#L46)


#### Performance Benchmarks

> **Note:** OpenCL generates uncompressed keys. Compressed keys can be derived from uncompressed ones with minimal overhead.

| GPU Model                   | CPU                 | Key Range (Bits) | Grid Size (Bits) | Effective Keys/s (~)   |
|-----------------------------|---------------------|------------------|------------------|------------------------|
| AMD Radeon RX 7900 XTX      | AMD Ryzen 7 9800X3D | 160              | 19               | 15,000,000 keys/s      |
| AMD Radeon RX 7900 XTX      | AMD Ryzen 7 9800X3D | 256              | 19               | 11,000,000 keys/s      |
| NVIDIA RTX 3070 Laptop      | AMD Ryzen 7 5800H   | 160              | 19               |  6,000,000 keys/s      |
| NVIDIA RTX 3070 Laptop      | AMD Ryzen 7 5800H   | 256              | 19               |  4,000,000 keys/s      |
| NVIDIA RTX 3090             | AMD Ryzen 9 3950X   | 160              | 19               | 11,000,000 keys/s      |
| NVIDIA RTX 3090             | AMD Ryzen 9 3950X   | 256              | 19               |  8,000,000 keys/s      |
| NVIDIA RTX A3000            | Intel i7-11850H     | 256              | 19               |  3,000,000 keys/s      |
| NVIDIA RTX A3000            | Intel i7-11850H     | 160              | 19               |  5,000,000 keys/s      |
| AMD Radeon 8060S            | AMD AI MAX+ 395     | 256              | 16               |  9,200,000 keys/s      |
| AMD Radeon 8060S            | AMD AI MAX+ 395     | 160              | 16               | 11,000,000 keys/s      |


## Collision Probability and Security Considerations

> Isn't it impossible to find collisions?

The likelihood of discovering a collision—two different inputs that produce the same output hash—is **astronomically low** when using secure cryptographic functions like **SHA-256** and **RIPEMD-160**, which are employed in Bitcoin address generation.

However, discussions around potential vulnerabilities, theoretical attacks, or edge cases exist in the cryptography and Bitcoin communities.

For more in-depth information on collision resistance, address reuse risks, and cryptographic hash functions, refer to the following resources:

- [How to deal with collisions in Bitcoin addresses – Crypto StackExchange](https://crypto.stackexchange.com/questions/33821/how-to-deal-with-collisions-in-bitcoin-addresses)
- [Why haven't any SHA-256 collisions been found yet? – Crypto StackExchange](https://crypto.stackexchange.com/questions/47809/why-havent-any-sha-256-collisions-been-found-yet)
- [bitcoin-wallet-finder – Results and discussion](https://github.com/treyyoder/bitcoin-wallet-finder#results)
- [PKGenerator_Checker – Instructions](https://github.com/Frankenmint/PKGenerator_Checker#instructions)
- [BitBruteForce-Wallet – Requirements and usage](https://github.com/Xefrok/BitBruteForce-Wallet#requeriments)
- [New Records in Collision Attacks on RIPEMD-160 and SHA-256 (ePrint 2023/285)](https://eprint.iacr.org/2023/285) – Li et al. present new records in collision attacks: 40-step RIPEMD-160 and 39-step semi-free-start SHA-256. Both hash functions are fundamental to Bitcoin address generation.

### ⚠️ Security Advisory: Android RNG Vulnerability (2013) and Simulation via BitcoinAddressFinder
In 2013, a serious vulnerability was discovered in Android’s `SecureRandom` implementation. It caused Bitcoin private keys to be exposed due to reused or predictable random values during ECDSA signature creation. This problem affected many wallet apps that generated keys directly on Android devices.

BitcoinAddressFinder can be used to simulate and analyze this type of attack. With small changes, it can reproduce faulty random number generators by:
* using fixed or repeating `k` values
* limiting entropy to 16, 32, or 64 bits
* replacing the secure RNG with a weak or deterministic version

This makes it possible to test and study:
* how r-collisions happen in ECDSA signatures
* how easy it is to find reused `k` values
* how quickly a private key can be recovered
* how secure different RNG implementations really are

BitcoinAddressFinder can generate millions of key pairs quickly. This allows researchers to create and scan large keyspaces under controlled RNG conditions. All results can be verified using the built-in self-test feature or compared against known addresses in the LMDB database.

This kind of simulation is useful for:
* learning about signature security
* building training examples for audits or courses
* checking RNG quality in real wallets or custom apps

References:
* [Wikipedia: RNG Attack](https://en.wikipedia.org/wiki/Random_number_generator_attack)
* [Crypto.SE: Android SecureRandom + r-Collisions](https://crypto.stackexchange.com/questions/9694/technical-details-of-attack-on-android-bitcoin-usage-of-securerandom)
* [The Register: Android Bug Batters Wallets](https://www.theregister.com/2013/08/12/android_bug_batters_bitcoin_wallets/)
* [Google Blog: SecureRandom Fixes](https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html)
* [bitcoin.org Alert (2013-08-11)](https://bitcoin.org/en/alert/2013-08-11-android)

### Example: Weak RNG in an embedded Ethereum wallet (TinyMT32 seeded from `micros()`)

Issue: https://github.com/AlphaWallet/Web3E/issues/31

Credits / Found by Jean-Philippe Aumasson: https://github.com/veorq

`KeyID::generatePrivateKey()` relies on `random_buffer()`, which uses `tinyMT32` as its PRNG. The PRNG is initialized only once using a 32-bit seed derived from `micros()`.

This is *not a cryptographically secure RNG,* and the 32-bit timer seed makes the generated private keys predictable and brute-forceable. All keys produced by the current implementation are vulnerable. A hardware CSPRNG or proper DRBG must be used instead.

Links:
* https://github.com/AlphaWallet/Web3E/blob/c19324cc209b11fd4389d1c782a7e6ffbc391cfb/src/KeyID.cpp#L48-L50
* https://github.com/AlphaWallet/Web3E/blob/c19324cc209b11fd4389d1c782a7e6ffbc391cfb/src/Trezor/rand.c#L362-L364

Although this vulnerability originates from an **Ethereum-based embedded wallet**, it demonstrates the same class of weaknesses relevant to Bitcoin and all ECDSA-based systems: **private keys generated from low-entropy or predictable random sources**.

In this implementation, the wallet uses `TinyMT32` as its PRNG and seeds it only once with a 32-bit microsecond timer:

```tinymt32_init(&tinymt, (uint32_t)micros());```

TinyMT32 is *not* a cryptographically secure RNG, and seeding it with a 32-bit timestamp collapses the effective key space from 2²⁵⁶ to only 2³² possible seeds. An attacker who can approximate the device’s boot time can brute-force all feasible seeds, reproduce the PRNG stream, and reconstruct the wallet’s private keys.

This resembles the historic Android `SecureRandom` vulnerability: the elliptic-curve cryptography itself is secure, but the **randomness used to create keys is not**.

BitcoinAddressFinder can simulate this type of scenario by generating keys using intentionally weak or deterministic RNGs and scanning the resulting restricted key ranges. This makes it possible to study how insecure RNGs can compromise wallets.

## Similar projects
* The [LBC](https://lbc.cryptoguru.org/) is optimized to find keys for the [Bitcoin Puzzle Transaction](https://privatekeys.pw/puzzles/bitcoin-puzzle-tx). It require communication to a server, doesn't support altcoin and pattern matching.
* https://privatekeys.pw/scanner/bitcoin
* https://allprivatekeys.com/get-lucky
* https://allprivatekeys.com/vanity-address
* https://github.com/treyyoder/bitcoin-wallet-finder
* https://github.com/albertobsd/keyhunt
* https://github.com/mvrc42/bitp0wn
* https://github.com/JeanLucPons/BTCCollider
* https://github.com/JeanLucPons/VanitySearch
* https://github.com/JamieAcharya/Bitcoin-Private-Key-Finder
* https://github.com/mingfunwong/all-bitcoin-private-key
* https://github.com/Frankenmint/PKGenerator_Checker
* https://github.com/Henshall/BitcoinPrivateKeyHunter
* https://github.com/Xefrok/BitBruteForce-Wallet
* https://github.com/Isaacdelly/Plutus
* https://github.com/Noname400/Hunt-to-Mnemonic
* https://github.com/Py-Project/Bitcoin-wallet-cracker
* https://github.com/johncantrell97/bip39-solver-gpu
* https://github.com/ilkerccom/bitcrackrandomiser
* https://btcpuzzle.info/

### Deep learning private key prediction
An export of the full database can be used to predict private keys with deep learning. A funny idea: https://github.com/DRSZL/BitcoinTensorFlowPrivateKeyPrediction

## Learn more
* https://learnmeabitcoin.com/technical/keys/public-key/

## Known Issues

### Hybrid Graphics Performance (Low Throughput)

Laptops with hybrid graphics—using both integrated (iGPU) and discrete (dGPU) GPUs—may suffer from significantly reduced performance when running compute-intensive OpenCL workloads like BitcoinAddressFinder. This is often due to:

- Shared memory between CPU and GPU
- Bandwidth limitations
- Automatic GPU switching (e.g., NVIDIA Optimus, AMD Enduro)
- Suboptimal GPU selection by drivers

#### Affected Devices and Recommendations

| Manufacturer       | Affected Series/Models                          | Recommendation                           |
|--------------------|--------------------------------------------------|------------------------------------------|
| **HP**             | ZBook G3, G4, G5, G7                             | Enter BIOS → set **Graphics** to *Discrete Only* |
| **Lenovo**         | ThinkPad X, T, and P Series (hybrid configs)     | Use **Lenovo Vantage** → Disable Hybrid Graphics |
| **Dell**           | Inspiron, XPS, Precision (with Optimus)          | BIOS → Disable Hybrid Mode (if available) |
| **MSI**            | Gaming laptops with switchable graphics          | Use **Dragon Center** to select dGPU     |
| **Razer**          | Blade models with NVIDIA Optimus                 | Use **Razer Synapse** to enforce dGPU use |
| **Apple (Intel)**  | MacBook Pro (pre-2021 with dual GPUs)            | macOS → Disable *Automatic Graphics Switching* in Energy Preferences |

> If your laptop uses hybrid graphics, always ensure that the **discrete GPU** is explicitly selected for OpenCL workloads to avoid severe performance bottlenecks.

## Future improvements
- Refactor the entire key generation infrastructure to support a key provider. This provider should be configurable to supply private keys from various sources, such as Random, Secrets File, Key Range, and others. All consumers should retrieve keys from this provider.

### KeyProvider
- Key generation within a specific key range. See #27
Wished from themaster:
```
"privateKeyStartHex" : "0000000000000000000000000000000000000000000000037e26d5b1f3afe216"
"privateKeyEndHex" : "0000000000000000000000000000000000000000000000037e26d5b1ffffffff"
```
Wished from Ulugbek:
```
// Search started from given address. Would be nice if it can save last position...
"sequentalSearch" : true,
"startAddress" : xxxxxxxx,

// Random search with batches, here 100000. I,e. some random number is found and after 100000 sequental addresses should be checked.
"searchAsBatches" : true,
"searchBatchQuantity" : 100000,


// Random search within Address Space, with batches, here 100000.
"searchAsBatches" : true,
"searchAddressStart" : xxxxxxx,
"searchAddressEnd" : xxxxxxxy,
"searchBatchQuantity" : 100000
```

- Incomplete Seed-Phrase as Private KeyProvider. Wished from @mirasu See #38
- Socket KeyProvider for independend KeyProvider via byte protocol
  - Ideas might be a screen recorder and use the visible screen downscaled as 256 bit input
- KeyProvider must get the grid size to increment properly on incremental based Producer
- ExecutableKeyProvider gets data from stdout

-----


## Legal

**BitcoinAddressFinder is not intended for malicious use**, and **you are solely responsible** for complying with your local laws, international regulations, and ethical standards.

This software must **not** be configured or used to attempt unauthorized access to cryptocurrency assets (e.g., scanning for RIPEMD-160 address collisions to gain access to third-party funds).  
Such activities are likely illegal in most jurisdictions and may carry serious penalties.

---

### ✅ Permitted Use Cases

You may use BitcoinAddressFinder for legitimate and research-focused purposes, such as:

- **Recovering lost private keys** associated with your own known public addresses
- Verifying whether generated addresses have ever been used to **prevent collisions**
- Running **performance benchmarks** and OpenCL testing
- Generating **vanity addresses** for personal or demonstrative use
- Conducting **offline cryptographic research** and educational exploration

---

### 🚫 Prohibited Use Cases

You must not use this tool for:

- **Gaining unauthorized access to cryptocurrency or wallet funds**
- Circumventing access controls or exploiting systems
- Engaging in unethical behavior or violating terms of service

---

### Legal References by Jurisdiction

Below is a non-exhaustive collection of legal frameworks that **may** apply depending on your jurisdiction.

> ⚠️ **Important Note**: The following information is provided for informational purposes only and **does not constitute legal advice**.  
> You should always consult with a **qualified legal professional** before engaging in any activity related to cryptographic systems or asset recovery.  
> I merely present relevant legal context, not binding interpretations or actionable recommendations.

#### Germany

- **§ 202c StGB** – *Vorbereiten des Ausspähens und Abfangens von Daten*  
  (Preparation of spying or intercepting data)
- **OLG Braunschweig, Beschluss vom 18.09.2024 – 1 Ws 185/24**  
  In einem aufsehenerregenden Fall entschied das OLG, dass der Zugriff auf eine Wallet mittels eines bekannten (nicht rechtswidrig erlangten) Seeds **nicht** als Straftat im Sinne der §§ 202a, 263a oder 303a StGB gewertet werden kann.  
  Der Angeklagte hatte eine Wallet für einen Dritten erstellt und sich später mittels der Seed-Phrase Zugriff auf Token im Wert von rund 2,5 Mio. € verschafft.  
  Das Gericht urteilte jedoch:

  - **Kein Diebstahl**: Kryptowährungen sind keine „Sachen“ im Sinne des § 242 StGB.  
  - **Kein Ausspähen von Daten (§ 202a StGB)**: Der Zugriff mittels bekannter Passwörter ist kein *Überwinden* einer Zugangssicherung.  
  - **Kein Computerbetrug (§ 263a StGB)**: Eine Krypto-Transaktion impliziert keine „Täuschung“ oder „Miterklärung einer Berechtigung“.  
  - **Keine Datenveränderung (§ 303a StGB)**: Die eigentliche Änderung erfolgt durch die Blockchain-Netzwerkbetreiber – nicht durch den User selbst.

  > 🔍 Fazit: Der *„Kryptodiebstahl“* per bekanntem Seed ist unter Umständen **nicht strafbar** – bleibt aber **zivilrechtlich angreifbar**.  
  > Quelle: [OLG Braunschweig Beschluss 1 Ws 185/24 (juris.de)](https://www.juris.de/static/infodienst/autoren/D_NJRE001604034.htm)  
  > Bericht: [heise.de Artikel vom 11.07.2025](https://www.heise.de/news/Oberlandesgericht-Virtuelle-Entwendung-von-Kryptowerten-bleibt-straflos-10484771.html)

#### United States

- **Computer Fraud and Abuse Act (CFAA)**  
  Prohibits unauthorized access to protected computers, including use of tools for circumvention

- **Digital Millennium Copyright Act (DMCA)**  
  Sections on anti-circumvention tools and reverse engineering may apply in specific contexts

#### European Union

- **General Data Protection Regulation (GDPR)**  
  While not directly related, use of personally identifiable data or address targeting must comply

- **Directive 2013/40/EU** on Attacks Against Information Systems  
  Criminalizes the creation or possession of tools designed for unauthorized access

#### Other Notable References

- **UK**: Computer Misuse Act 1990  
- **Canada**: Criminal Code Sections 342.1 & 430  
- **Australia**: Criminal Code Act 1995 – Part 10.7 – Computer Offences

---

> ⚠️ The authors and maintainers of BitcoinAddressFinder assume **no responsibility** for how the tool is used.  
> It is your duty to ensure compliance with all relevant legal and ethical standards in your country and jurisdiction.

If in doubt, consult with a legal professional before using this software for anything beyond educational or personal purposes.

## License

It is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.
Some subprojects have a different license.

This package is [Treeware](https://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/bernardladenthin/BitcoinAddressFinder) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.

[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fbernardladenthin%2FBitcoinAddressFinder.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fbernardladenthin%2FBitcoinAddressFinder?ref=badge_large)


================================================
FILE: TEST_WRITING_GUIDE.md
================================================
# Unit Test Writing Guide — BitcoinAddressFinder (Project-Specific Supplement)

This guide contains **project-specific** test conventions that supplement the generic Java TDD skill (`.claude/skills/java-tdd-guide.md`). For general test conventions (AAA structure, Hamcrest assertions, editor folds, naming, data providers, etc.), refer to the generic guide.

---

## 1. Custom Marker Annotations

Apply the appropriate marker annotation alongside `@Test` when applicable:

| Annotation | When to use |
|---|---|
| `@AwaitTimeTest` | Test involves timing assertions (`Duration.ofMillis`, `greaterThan`) |
| `@ToStringTest` | Test validates a `toString()` implementation |
| `@OpenCLTest` | Test requires an OpenCL-capable device |

Example:

```java
@ToStringTest
@Test
public void toString_whenCalled_containsClassNameAndIdentityHash() {
    // ...
    assertThat(output, matchesPattern("ProducerJava@\\p{XDigit}+"));
}
```

---

## 2. Timing / Await Tests

Tests that assert on timing durations must:
1. Be annotated with `@AwaitTimeTest`.
2. Use `AwaitTimeTests.AWAIT_DURATION` (20 s) as the configurable duration.
3. Use `AwaitTimeTests.IMPRECISION` (2 s) as the tolerance.
4. Override the static constant before the test runs.

```java
@AwaitTimeTest
@Test
public void interrupt_keysQueueNotEmpty_waitedForDuration()
        throws IOException, InterruptedException {
    ConsumerJava.AWAIT_DURATION_QUEUE_EMPTY = AwaitTimeTests.AWAIT_DURATION;

    // ... arrange ...

    long beforeAct = System.currentTimeMillis();
    consumerJava.interrupt();
    long afterAct = System.currentTimeMillis();

    Duration waitTime = Duration.ofMillis(afterAct - beforeAct);

    assertThat(waitTime, is(greaterThan(
        ConsumerJava.AWAIT_DURATION_QUEUE_EMPTY.minus(AwaitTimeTests.IMPRECISION)
    )));
}
```

---

## 3. Static Address Constants — Never Hard-Code Raw Strings

Use the static address enums and helper classes for test data:

| Class | Purpose |
|---|---|
| `StaticKey` | A single known private key with all derived forms |
| `TestAddresses42` | A set of addresses derived from seed 42 |
| `TestAddresses1337` | A set of addresses derived from seed 1337 |
| `P2PKH` enum | Known valid P2PKH public addresses with expected hashes |
| `P2SH` enum | Known valid P2SH script hash addresses |
| `P2WPKH` enum | Known valid native SegWit addresses |
| `StaticUnsupportedAddress` enum | Addresses that must be rejected |

---

## 4. Platform Assumptions

Tests that require a specific platform conditionally skip using assume classes:

```java
@OpenCLTest
@Test
public void build_oneOpenCLDevice_returnsPlatformWithDevice() {
    new OpenCLPlatformAssume().assumeOpenCLLibraryLoadableAndOneOpenCL2_0OrGreaterDeviceAvailable();
    // test body
}
```

Available assume classes:
- `OpenCLPlatformAssume` — OpenCL GPU device required
- `LMDBPlatformAssume` — LMDB native library required
- `PlatformAssume` — generic OS assumptions

---

## 5. OpenCL Tests

### When `@OpenCLTest` + assume IS required

A test must be annotated with `@OpenCLTest` and call `assumeOpenCLLibraryLoadableAndOneOpenCL2_0OrGreaterDeviceAvailable()` as its **first statement** when the test body invokes OpenCL API functions:

- `CL.stringFor_*` or any `CL.*` native call
- `OpenCLBuilder.build()` or methods that load/query the OpenCL runtime
- Any code path triggering native library loading

**Rules:**
- Annotate with `@OpenCLTest`.
- Call assume as the **first statement**.
- Do not gate the entire class — only gate individual methods.

### When `@OpenCLTest` + assume is NOT required

Tests that **only** use JOCL wrapper types (`cl_device_id`, `cl_context_properties`, `cl_platform_id`) as plain Java objects — without calling native OpenCL API functions — do **not** need `@OpenCLTest`.

**Decision rule:** "Does this test call any method that invokes a native OpenCL function?" If yes → `@OpenCLTest` + assume. If no → no annotation needed.

---

## 6. LMDB / File System Tests

Use project-specific helpers for LMDB test databases:

```java
TestAddressesLMDB testAddressesLMDB = new TestAddressesLMDB();
TestAddressesFiles testAddresses = new TestAddressesFiles(compressed);
File lmdbFolderPath = testAddressesLMDB.createTestLMDB(folder, testAddresses, useStaticAmount, false);
```

For tests that share LMDB setup, extend `LMDBBase`:

```java
public class MyLMDBTest extends LMDBBase {
    // LMDBBase provides: @Rule folder, network, keyUtility, and LMDB helpers
}
```

---

## 7. Shared Test Fields

Common shared fields for BitcoinAddressFinder tests:

```java
private final Network network = new NetworkParameterFactory().getNetwork();
private final KeyUtility keyUtility = new KeyUtility(network, new ByteBufferUtility(false));
private final BitHelper bitHelper = new BitHelper();
```

---

## 8. Producer Tests

Tests for `Producer` subclasses can extend `AbstractProducerTest` which provides shared verify helpers:

```java
AbstractProducerTest.verifyInitProducer(producer);
AbstractProducerTest.verifyReleaseProducer(producer);
```

---

## 9. Socket Test Utilities

- Use `TestTimeProvider` constants for socket timeouts:
  ```java
  config.timeout = TestTimeProvider.DEFAULT_SOCKET_TIMEOUT;
  config.readRetryCount = TestTimeProvider.DEFAULT_RETRY_COUNT;
  ```
- Use `ConnectionUtils.waitUntilTcpPortOpen(...)` for server readiness checks.

---

## 10. Accessing Test Resources

Use `Path.of("src","test","resources")` to locate test resource files:

```java
private final Path resourceDirectory = Path.of("src", "test", "resources");
private final Path testRoundtripDirectory = resourceDirectory.resolve("roundtrip");
private final Path configFile = testRoundtripDirectory.resolve("config_AddressFilesToLMDB.json");
```


================================================
FILE: build.bat
================================================
call mvn clean
call mvn compile test assembly:single

================================================
FILE: examples/addresses/fileContainingAddresses0.txt
================================================
# comment
12R4kPeSK6i9427ctH15j2NcJ1ST1FT21C,0
13z55AGS14pSPiPpMqAAFHb576tSmSmR77,1
14rDamyE53BNLPSj4cku6ZXiW6xbBdMJ97,2
15ArtCgi3wmpQAAfYx4riaFmo4prJA4VsK,3


================================================
FILE: examples/addresses/fileContainingAddresses1.tsv
================================================
# comment
15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC;1337
17LYqSzhuWksgoGsgakiWBG8PmbCKyrrac;1337
17RTTUAiiPqUTKtEggJPec8RxLMi2n9EZ9;1337


================================================
FILE: examples/addresses/fileContainingAddresses2.csv
================================================
# comment
17aDRzRQK8ccBLVBzsms3ZasVKc9q3o3Qk
18LDvu2nqr8a5AK9AHkkqDK6Z65dzbTgtn
1966U1pjj15tLxPXZ19U48c99EJDkdXeqb


================================================
FILE: examples/config_AddressFilesToLMDB.json
================================================
{
  "command": "AddressFilesToLMDB",
  "addressFilesToLMDB": {
    "addressesFiles": [
      "addresses/fileContainingAddresses0.txt",
      "addresses/fileContainingAddresses1.tsv",
      "addresses/fileContainingAddresses2.csv"
    ],
    "lmdbConfigurationWrite": {
      "initialMapSizeInMiB": 16,
      "deleteEmptyAddresses": false,
      "staticAmount": 0,
      "useStaticAmount": true,
      "increaseMapAutomatically": true,
      "increaseSizeInMiB": 1,
      "lmdbDirectory": "lmdb",
      "useProxyOptimal": true,
      "logStatsOnInit": true,
      "logStatsOnClose": true,
      "loadToMemoryCacheOnInit" : false,
      "disableAddressLookup" : false
    }
  }
}

================================================
FILE: examples/config_Find_1OpenCLDevice.json
================================================
{
  "command": "Find",
  "finder": {
    "keyProducerJavaIncremental": [
        {
            "keyProducerId": "exampleKeyProducerJavaIncremental",
            "startAddress" : "0000000000000000000000000000000000000000000000000000000000000002",
            "endAddress"   : "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
        }
    ],
    "keyProducerJavaBip39": [
        {
            "keyProducerId": "exampleKeyProducerJavaBip39Id",
            "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
            "passphrase": "correct horse battery staple",
            "hardened" : false,
            "bip32Path": "M/44H/0H/0H/0",
            "creationTimeSeconds": 1650000000
        }
    ],
    "keyProducerJavaRandom": [
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      }
    ],
    "keyProducerJavaSocket": [
        {
            "keyProducerId": "exampleKeyProducerJavaSocket",
            "logReceivedSecret": true,
            "maxWorkSize": 16777216,
            "host": "localhost",
            "port": 5555,
            "mode": "SERVER",
            "timeout": 3000,
            "connectionRetryCount": 5,
            "readRetryCount": 5,
            "retryDelayMillisConnect": 1000,
            "retryDelayMillisRead": 1000,
            "readPartialRetryCount": 5,
            "readPartialRetryDelayMillis": 20
        }
    ],
	"keyProducerJavaWebSocket": [
		{
			"keyProducerId": "exampleKeyProducerJavaWebSocket",
			"logReceivedSecret": true,
			"port": 8080,
			"timeout": 1000
		}
	],
	"keyProducerJavaZmq": [
		{
			"keyProducerId": "exampleKeyProducerJavaZmq",
			"logReceivedSecret": true,
			"address": "tcp://127.0.0.1:5557",
			"mode": "BIND",
			"timeout": -1
		}
	],
    "consumerJava": {
      "lmdbConfigurationReadOnly": {
        "lmdbDirectory": "lmdb",
        "useProxyOptimal": true,
        "logStatsOnInit": true,
        "logStatsOnClose": false,
        "loadToMemoryCacheOnInit" : false,
        "disableAddressLookup" : false
      },
      "printStatisticsEveryNSeconds": 10,
      "threads": 8,
      "delayEmptyConsumer": 50,
      "queueSize": 4,
      "runtimePublicKeyCalculationCheck": false,
      "enableVanity": false,
      "vanityPattern": "1[Ee][Mm][Ii][Ll].*"
    },
    "producerJava": [],
    "producerJavaSecretsFiles": [],
    "producerOpenCL": [
      {
        "platformIndex": 0,
        "deviceType": -1,
        "deviceIndex": 0,
        "maxResultReaderThreads": 4,
        "delayBlockedReader": 50,
        "keyProducerId": "exampleKeyProducerSecureRandomId",
        "batchSizeInBits": 18,
        "loopCount" : 4,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      }
    ]
  }
}

================================================
FILE: examples/config_Find_1OpenCLDeviceAnd2CPUProducer.json
================================================
{
  "command": "Find",
  "finder": {
    "keyProducerJavaRandom": [
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_1",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_2",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_3",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      }
    ],
    "consumerJava": {
      "lmdbConfigurationReadOnly": {
        "lmdbDirectory": "lmdb",
        "useProxyOptimal": true,
        "logStatsOnInit": true,
        "logStatsOnClose": false,
        "loadToMemoryCacheOnInit" : false,
        "disableAddressLookup" : false
      },
      "printStatisticsEveryNSeconds": 10,
      "threads": 8,
      "delayEmptyConsumer": 50,
      "queueSize": 4,
      "runtimePublicKeyCalculationCheck": false,
      "enableVanity": false,
      "vanityPattern": "1[Ee][Mm][Ii][Ll].*"
    },
    "producerJava": [
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_2",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_3",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      }
    ],
    "producerJavaSecretsFiles": [],
    "producerOpenCL": [
      {
        "platformIndex": 0,
        "deviceType": -1,
        "deviceIndex": 0,
        "maxResultReaderThreads": 4,
        "delayBlockedReader": 50,
        "keyProducerId": "exampleKeyProducerSecureRandomId_1",
        "batchSizeInBits": 18,
        "loopCount" : 4,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      }
    ]
  }
}

================================================
FILE: examples/config_Find_8CPUProducer.json
================================================
{
  "command": "Find",
  "finder": {
    "keyProducerJavaRandom": [
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_1",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_2",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_3",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_4",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_5",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_6",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_7",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_8",
        "keyProducerJavaRandomInstance": "SECURE_RANDOM",
        "customSeed": 0,
        "privateKeyMaxNumBits": 256
      }
    ],
    "consumerJava": {
      "lmdbConfigurationReadOnly": {
        "lmdbDirectory": "lmdb",
        "useProxyOptimal": true,
        "logStatsOnInit": true,
        "logStatsOnClose": false
      },
      "printStatisticsEveryNSeconds": 10,
      "threads": 4,
      "delayEmptyConsumer": 50,
      "queueSize": 4,
      "runtimePublicKeyCalculationCheck": false,
      "enableVanity": false,
      "vanityPattern": "1[Ee][Mm][Ii][Ll].*"
    },
    "producerJava": [
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_1",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_2",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_3",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_4",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_5",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_6",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_7",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      },
      {
        "keyProducerId": "exampleKeyProducerSecureRandomId_8",
        "batchSizeInBits": 14,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": false,
        "runOnce": false
      }
    ],
    "producerJavaSecretsFiles": [],
    "producerOpenCL": []
  }
}

================================================
FILE: examples/config_Find_SecretsFile.json
================================================
{
  "command": "Find",
  "finder": {
    "keyProducerJavaRandom": [],
    "consumerJava": {
      "lmdbConfigurationReadOnly": {
        "lmdbDirectory": "lmdb",
        "useProxyOptimal": true,
        "logStatsOnInit": true,
        "logStatsOnClose": false,
        "loadToMemoryCacheOnInit" : false,
        "disableAddressLookup" : false
      },
      "printStatisticsEveryNSeconds": 10,
      "threads": 4,
      "delayEmptyConsumer": 50,
      "queueSize": 4,
      "runtimePublicKeyCalculationCheck": false,
      "enableVanity": false,
      "vanityPattern": "1[Ee][Mm][Ii][Ll].*"
    },
    "producerJava": [],
    "producerJavaSecretsFiles": [
      {
        "files": [
          "secrets/fileContainingSecrets_BIG_INTEGER.txt"
        ],
        "secretFormat": "BIG_INTEGER",
        "batchSizeInBits": 0,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": true,
        "runOnce": true
      },
      {
        "files": [
          "secrets/fileContainingSecrets_DUMPED_RIVATE_KEY.txt"
        ],
        "secretFormat": "DUMPED_RIVATE_KEY",
        "batchSizeInBits": 0,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": true,
        "runOnce": true
      },
      {
        "files": [
          "secrets/fileContainingSecrets_SHA256.txt"
        ],
        "secretFormat": "SHA256",
        "batchSizeInBits": 0,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": true,
        "runOnce": true
      },
      {
        "files": [
          "secrets/fileContainingSecrets_STRING_DO_SHA256.txt"
        ],
        "secretFormat": "STRING_DO_SHA256",
        "batchSizeInBits": 0,
        "batchUsePrivateKeyIncrement": true,
        "logSecretBase": true,
        "runOnce": true
      }
    ],
    "producerOpenCL": []
  }
}

================================================
FILE: examples/config_LMDBToAddressFile.json
================================================
{
  "command": "LMDBToAddressFile",
  "lmdbToAddressFile": {
    "lmdbConfigurationReadOnly": {
      "lmdbDirectory": "lmdb",
      "useProxyOptimal": true,
      "logStatsOnInit": false,
      "logStatsOnClose": false
    },
    "addressesFile": "export.txt",
    "addressFileOutputFormat": "HexHash"
  }
}

================================================
FILE: examples/config_OpenCLInfo.json
================================================
{
  "command": "OpenCLInfo"
}

================================================
FILE: examples/logbackConfiguration.xml
================================================
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%date{ISO8601} [%thread] %-5level %logger{200} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="info">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>


================================================
FILE: examples/run_AddressFilesToLMDB.bat
================================================
rem start /low java ^
java ^
--add-opens java.base/java.lang=ALL-UNNAMED ^
--add-opens java.base/java.io=ALL-UNNAMED ^
--add-opens java.base/java.nio=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.ref=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED ^
--add-opens java.base/sun.nio.ch=ALL-UNNAMED ^
--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED ^
-Xms512m ^
-Xmx512m ^
-Dlogback.configurationFile=logbackConfiguration.xml ^
-jar ^
bitcoinaddressfinder-1.5.0-jar-with-dependencies.jar ^
config_AddressFilesToLMDB.json
rem >> log_AddressFilesToLMDB.txt 2>&1


================================================
FILE: examples/run_Find_1OpenCLDevice.bat
================================================
rem start /low java ^
java ^
--add-opens java.base/java.lang=ALL-UNNAMED ^
--add-opens java.base/java.io=ALL-UNNAMED ^
--add-opens java.base/java.nio=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.ref=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED ^
--add-opens java.base/sun.nio.ch=ALL-UNNAMED ^
--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED ^
-Xms512M ^
-Xmx16G ^
-Dlogback.configurationFile=logbackConfiguration.xml ^
-jar ^
bitcoinaddressfinder-1.5.0-jar-with-dependencies.jar ^
config_Find_1OpenCLDevice.json
rem >> log_Find_1OpenCLDevice.txt 2>&1


================================================
FILE: examples/run_Find_1OpenCLDeviceAnd2CPUProducer.bat
================================================
rem start /low java ^
java ^
--add-opens java.base/java.lang=ALL-UNNAMED ^
--add-opens java.base/java.io=ALL-UNNAMED ^
--add-opens java.base/java.nio=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.ref=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED ^
--add-opens java.base/sun.nio.ch=ALL-UNNAMED ^
--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED ^
-Xms512M ^
-Xmx16G ^
-Dlogback.configurationFile=logbackConfiguration.xml ^
-jar ^
bitcoinaddressfinder-1.5.0-jar-with-dependencies.jar ^
config_Find_1OpenCLDeviceAnd2CPUProducer.json
rem >> log_Find_1OpenCLDeviceAnd2CPUProducer.txt 2>&1


================================================
FILE: examples/run_Find_8CPUProducer.bat
================================================
rem start /low java ^
java ^
--add-opens java.base/java.lang=ALL-UNNAMED ^
--add-opens java.base/java.io=ALL-UNNAMED ^
--add-opens java.base/java.nio=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.ref=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED ^
--add-opens java.base/sun.nio.ch=ALL-UNNAMED ^
--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED ^
-Xms512M ^
-Xmx16G ^
-Dlogback.configurationFile=logbackConfiguration.xml ^
-jar ^
bitcoinaddressfinder-1.5.0-jar-with-dependencies.jar ^
config_Find_8CPUProducer.json
rem >> log_Find_8CPUProducer.txt 2>&1


================================================
FILE: examples/run_Find_SecretsFile.bat
================================================
rem start /low java ^
java ^
--add-opens java.base/java.lang=ALL-UNNAMED ^
--add-opens java.base/java.io=ALL-UNNAMED ^
--add-opens java.base/java.nio=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.ref=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED ^
--add-opens java.base/sun.nio.ch=ALL-UNNAMED ^
--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED ^
-Xms512M ^
-Xmx16G ^
-Dlogback.configurationFile=logbackConfiguration.xml ^
-jar ^
bitcoinaddressfinder-1.5.0-jar-with-dependencies.jar ^
config_Find_SecretsFile.json
rem >> log_Find_SecretsFile.txt 2>&1


================================================
FILE: examples/run_LMDBToAddressFile.bat
================================================
rem start /low java ^
java ^
--add-opens java.base/java.lang=ALL-UNNAMED ^
--add-opens java.base/java.io=ALL-UNNAMED ^
--add-opens java.base/java.nio=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.ref=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED ^
--add-opens java.base/sun.nio.ch=ALL-UNNAMED ^
--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED ^
-Xms512m ^
-Xmx512m ^
-Dlogback.configurationFile=logbackConfiguration.xml ^
-jar ^
bitcoinaddressfinder-1.5.0-jar-with-dependencies.jar ^
config_LMDBToAddressFile.json
rem >> log_LMDBToAddressFile.txt 2>&1


================================================
FILE: examples/run_OpenCLInfo.bat
================================================
rem start /low java ^
java ^
--add-opens java.base/java.lang=ALL-UNNAMED ^
--add-opens java.base/java.io=ALL-UNNAMED ^
--add-opens java.base/java.nio=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.ref=ALL-UNNAMED ^
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED ^
--add-opens java.base/sun.nio.ch=ALL-UNNAMED ^
--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED ^
-Xms512m ^
-Xmx512m ^
-Dlogback.configurationFile=logbackConfiguration.xml ^
-jar ^
bitcoinaddressfinder-1.5.0-jar-with-dependencies.jar ^
config_OpenCLInfo.json
rem >> log_OpenCLInfo.txt 2>&1


================================================
FILE: examples/secrets/fileContainingSecrets_BIG_INTEGER.txt
================================================
72155939486846849509759369733266486982821795810448245423168957390607644363272
39929263256442288830290225612580366403172818928633701045115663441379782969864
42379586058257162021782620237913525000692985364990081801945649219990416465578


================================================
FILE: examples/secrets/fileContainingSecrets_DUMPED_RIVATE_KEY.txt
================================================
5K2YUVmWfxbmvsNxCsfvArXdGXm7d5DC9pn4yD75k2UaSYgkXTh
5JVAXLpkZ21svEzwyimMHn5hAkWNqJq8uGxqUqcRrNb8F4Csp8V
5JXYuGrwSbyp8sKBmiLcvokqSnxALPjKWQMPJXZYyBWKof7c2pk


================================================
FILE: examples/secrets/fileContainingSecrets_SHA256.txt
================================================
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
58472980a1d3449939eadc2652370972d5007fa9c059ce84fb3ab98f544e4a08
5db1fee4b5703808c48078a76768b155b421b210c0761cd6a5d223f4d99f1eaa


================================================
FILE: examples/secrets/fileContainingSecrets_STRING_DO_SHA256.txt
================================================
test
test with space
1337


================================================
FILE: examples/websocket.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Bit Pattern Visualizer</title>
  <style>
    body {
      font-family: monospace;
      background-color: #f4f4f4;
      padding: 2rem;
    }
    h1 {
      text-align: center;
    }
    .grid {
      display: grid;
      grid-template-columns: repeat(16, 24px);
      grid-template-rows: repeat(16, 24px);
      gap: 2px;
      margin: 1rem auto;
      width: fit-content;
    }
    .cell {
      width: 24px;
      height: 24px;
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: #000;
      color: #fff;
      font-size: 10px;
      border-radius: 3px;
      cursor: pointer;
    }
    .cell.on {
      background-color: orange;
      color: #111;
    }
    .controls, .output {
      margin: 1rem auto;
      max-width: 800px;
    }
    textarea {
      width: 100%;
      height: 400px;
      font-family: monospace;
    }
    .output pre {
      background: white;
      padding: 1rem;
      border: 1px solid #ccc;
      overflow-x: auto;
      word-wrap: break-word;
      white-space: pre-wrap;
    }
    button {
      margin: 0.25rem;
      padding: 0.5rem 1rem;
    }
    .input-row {
      margin-top: 0.5rem;
    }
  </style>
</head>
<body>
  <h1>Bit Pattern Visualizer – Phase 1</h1>

  <div class="controls">
    <label>JavaScript: createNumber(round)</label>
    <textarea id="userScript">
// Example: Randomize only the last 71 LSB bits

function setBitsInRange(secret, randomBytes, bitOffset, bitCount) {
  for (let i = 0; i < bitCount; i++) {
    const bitVal = (randomBytes[Math.floor(i / 8)] >> (7 - (i % 8))) & 1;
    const bitIndex = bitOffset + i;
    const byteIndex = Math.floor(bitIndex / 8);
    const bitPos = 7 - (bitIndex % 8);
    if (bitVal) {
      secret[byteIndex] |= (1 << bitPos);
    }
  }
}

function create_random_LSB(bitsToSet) {
  const secret = new Uint8Array(32); // 256 bits = 32 bytes
  const bitOffset = 0; // start at LSB
  const randomBytes = new Uint8Array(Math.ceil(bitsToSet / 8));
  crypto.getRandomValues(randomBytes);
  setBitsInRange(secret, randomBytes, bitOffset, bitsToSet);
  return secret;
}

function createNumber(round) {
  return create_random_LSB(71);
}
</textarea>
    <div class="input-row">
      <label for="wsUrl">WebSocket URL:</label>
      <input type="text" id="wsUrl" value="ws://127.0.0.1:8080" />
      <button onclick="connectWebSocket()">Connect</button>
      <button onclick="disconnectWebSocket()">Disconnect</button>
    </div>
    <div class="input-row">
      <label for="delay">Interval (ms):</label>
      <input type="number" id="delay" value="1000" min="10" step="10">
    </div>
    <button onclick="startRounds()">Start</button>
    <button onclick="stopRounds()">Stop</button>
    <span id="roundDisplay">Round: 0</span>
  </div>

  <div id="bitGrid" class="grid"></div>

  <div class="output">
    <div><strong>Bit Sequence (MSB→LSB):</strong></div>
    <pre id="bitString"></pre>
    <div><strong>HEX:</strong></div>
    <pre id="hexString"></pre>
  </div>

  <script>
    let round = 0;
    let running = false;
    let intervalId = null;
    let ws = null;

    function connectWebSocket() {
      const url = document.getElementById("wsUrl").value;
      if (ws && ws.readyState <= 1) return;
      ws = new WebSocket(url);
      ws.onopen = () => console.log("WebSocket connected");
      ws.onmessage = (event) => console.log("Received:", event.data);
      ws.onerror = (err) => console.error("WebSocket error:", err);
      ws.onclose = () => console.log("WebSocket closed");
    }

    function disconnectWebSocket() {
      if (ws) ws.close();
    }

    function startRounds() {
      if (running) return;
      const delay = parseInt(document.getElementById("delay").value, 10) || 1000;
      running = true;
      intervalId = setInterval(() => {
        round++;
        document.getElementById("roundDisplay").textContent = `Round: ${round}`;
        runUserCode(round);
      }, delay);
    }

    function stopRounds() {
      running = false;
      clearInterval(intervalId);
    }

    function runUserCode(currentRound) {
      const code = document.getElementById("userScript").value;
      const wrapper = `(function(round) {
        ${code}
        return createNumber(round);
      })`;

      try {
        const generatedFunc = eval(wrapper);
        const result = generatedFunc(currentRound);
        updateGrid(result);

        if (ws && ws.readyState === WebSocket.OPEN) {
          ws.send(result);
        }
      } catch (e) {
        console.error("Error in user script:", e);
      }
    }

    function updateGrid(byteArray) {
  
Download .txt
gitextract_rp99wxvr/

├── .claude/
│   └── skills/
│       ├── java-tdd-guide/
│       │   └── SKILL.md
│       └── tdd/
│           └── SKILL.md
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── assembly.yml
│       ├── claude-code-review.yml
│       ├── claude.yml
│       ├── codeql.yml
│       ├── coverage.yml
│       └── matrixci.yml
├── .gitignore
├── .mvn/
│   └── jvm.config
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CODE_WRITING_GUIDE.md
├── LICENSE
├── README.md
├── TEST_WRITING_GUIDE.md
├── build.bat
├── examples/
│   ├── addresses/
│   │   ├── fileContainingAddresses0.txt
│   │   ├── fileContainingAddresses1.tsv
│   │   └── fileContainingAddresses2.csv
│   ├── config_AddressFilesToLMDB.json
│   ├── config_Find_1OpenCLDevice.json
│   ├── config_Find_1OpenCLDeviceAnd2CPUProducer.json
│   ├── config_Find_8CPUProducer.json
│   ├── config_Find_SecretsFile.json
│   ├── config_LMDBToAddressFile.json
│   ├── config_OpenCLInfo.json
│   ├── logbackConfiguration.xml
│   ├── run_AddressFilesToLMDB.bat
│   ├── run_Find_1OpenCLDevice.bat
│   ├── run_Find_1OpenCLDeviceAnd2CPUProducer.bat
│   ├── run_Find_8CPUProducer.bat
│   ├── run_Find_SecretsFile.bat
│   ├── run_LMDBToAddressFile.bat
│   ├── run_OpenCLInfo.bat
│   ├── secrets/
│   │   ├── fileContainingSecrets_BIG_INTEGER.txt
│   │   ├── fileContainingSecrets_DUMPED_RIVATE_KEY.txt
│   │   ├── fileContainingSecrets_SHA256.txt
│   │   └── fileContainingSecrets_STRING_DO_SHA256.txt
│   └── websocket.html
├── helper/
│   ├── bitinfocharts_com_scraping/
│   │   ├── scraping.py
│   │   └── start.bat
│   └── dumpwallet/
│       └── dumpwallet.py
├── pom.xml
├── skills/
│   └── tdd.md
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── net/
│   │   │       └── ladenthin/
│   │   │           └── bitcoinaddressfinder/
│   │   │               ├── AbstractPlaintextFile.java
│   │   │               ├── AbstractProducer.java
│   │   │               ├── AddressFile.java
│   │   │               ├── AddressFilesToLMDB.java
│   │   │               ├── AddressFormatNotAcceptedException.java
│   │   │               ├── AddressToCoin.java
│   │   │               ├── AddressTxtLine.java
│   │   │               ├── AddressType.java
│   │   │               ├── BIP39KeyProducer.java
│   │   │               ├── BIP39Wordlist.java
│   │   │               ├── Base36Decoder.java
│   │   │               ├── Bech32Helper.java
│   │   │               ├── BitHelper.java
│   │   │               ├── ByteBufferUtility.java
│   │   │               ├── ByteConversion.java
│   │   │               ├── Consumer.java
│   │   │               ├── ConsumerJava.java
│   │   │               ├── EndiannessConverter.java
│   │   │               ├── FileHelper.java
│   │   │               ├── Finder.java
│   │   │               ├── Interruptable.java
│   │   │               ├── KeyUtility.java
│   │   │               ├── LMDBToAddressFile.java
│   │   │               ├── NetworkParameterFactory.java
│   │   │               ├── OpenCLContext.java
│   │   │               ├── OpenCLGridResult.java
│   │   │               ├── OpenClTask.java
│   │   │               ├── PrivateKeyTooLargeException.java
│   │   │               ├── PrivateKeyValidator.java
│   │   │               ├── Producer.java
│   │   │               ├── ProducerJava.java
│   │   │               ├── ProducerJavaSecretsFiles.java
│   │   │               ├── ProducerOpenCL.java
│   │   │               ├── ProducerState.java
│   │   │               ├── ProducerStateProvider.java
│   │   │               ├── PublicKeyBytes.java
│   │   │               ├── RandomSecretSupplier.java
│   │   │               ├── ReadStatistic.java
│   │   │               ├── ReleaseCLObject.java
│   │   │               ├── SecretSupplier.java
│   │   │               ├── SecretsFile.java
│   │   │               ├── SeparatorFormat.java
│   │   │               ├── Shutdown.java
│   │   │               ├── Statistics.java
│   │   │               ├── cli/
│   │   │               │   └── Main.java
│   │   │               ├── configuration/
│   │   │               │   ├── CAddressFileOutputFormat.java
│   │   │               │   ├── CAddressFilesToLMDB.java
│   │   │               │   ├── CCommand.java
│   │   │               │   ├── CConfiguration.java
│   │   │               │   ├── CConsumerJava.java
│   │   │               │   ├── CFinder.java
│   │   │               │   ├── CKeyProducerJava.java
│   │   │               │   ├── CKeyProducerJavaBip39.java
│   │   │               │   ├── CKeyProducerJavaIncremental.java
│   │   │               │   ├── CKeyProducerJavaRandom.java
│   │   │               │   ├── CKeyProducerJavaRandomInstance.java
│   │   │               │   ├── CKeyProducerJavaReceiver.java
│   │   │               │   ├── CKeyProducerJavaSocket.java
│   │   │               │   ├── CKeyProducerJavaWebSocket.java
│   │   │               │   ├── CKeyProducerJavaZmq.java
│   │   │               │   ├── CLMDBConfigurationReadOnly.java
│   │   │               │   ├── CLMDBConfigurationWrite.java
│   │   │               │   ├── CLMDBToAddressFile.java
│   │   │               │   ├── CProducer.java
│   │   │               │   ├── CProducerJava.java
│   │   │               │   ├── CProducerJavaSecretsFiles.java
│   │   │               │   ├── CProducerOpenCL.java
│   │   │               │   ├── CSecretFormat.java
│   │   │               │   └── UnknownSecretFormatException.java
│   │   │               ├── eckey/
│   │   │               │   └── Secp256k1.java
│   │   │               ├── keyproducer/
│   │   │               │   ├── AbstractKeyProducer.java
│   │   │               │   ├── AbstractKeyProducerQueueBuffered.java
│   │   │               │   ├── ConnectionUtils.java
│   │   │               │   ├── KeyProducer.java
│   │   │               │   ├── KeyProducerIdIsNotUniqueException.java
│   │   │               │   ├── KeyProducerIdNullException.java
│   │   │               │   ├── KeyProducerIdUnknownException.java
│   │   │               │   ├── KeyProducerJava.java
│   │   │               │   ├── KeyProducerJavaBip39.java
│   │   │               │   ├── KeyProducerJavaIncremental.java
│   │   │               │   ├── KeyProducerJavaRandom.java
│   │   │               │   ├── KeyProducerJavaSocket.java
│   │   │               │   ├── KeyProducerJavaWebSocket.java
│   │   │               │   ├── KeyProducerJavaZmq.java
│   │   │               │   └── NoMoreSecretsAvailableException.java
│   │   │               ├── opencl/
│   │   │               │   ├── OpenCLBuilder.java
│   │   │               │   ├── OpenCLDevice.java
│   │   │               │   ├── OpenCLDeviceSelection.java
│   │   │               │   ├── OpenCLPlatform.java
│   │   │               │   └── OpenCLPlatformSelector.java
│   │   │               └── persistence/
│   │   │                   ├── Persistence.java
│   │   │                   ├── PersistenceUtils.java
│   │   │                   └── lmdb/
│   │   │                       └── LMDBPersistence.java
│   │   └── resources/
│   │       ├── copyfromhashcat/
│   │       │   ├── inc_common.cl
│   │       │   ├── inc_common.h
│   │       │   ├── inc_ecc_secp256k1.cl
│   │       │   ├── inc_ecc_secp256k1.h
│   │       │   ├── inc_hash_ripemd160.cl
│   │       │   ├── inc_hash_ripemd160.h
│   │       │   ├── inc_hash_sha256.cl
│   │       │   ├── inc_hash_sha256.h
│   │       │   ├── inc_platform.cl
│   │       │   ├── inc_platform.h
│   │       │   ├── inc_types.h
│   │       │   └── inc_vendor.h
│   │       ├── inc_defines.h
│   │       ├── inc_ecc_secp256k1custom.cl
│   │       ├── mnemonic/
│   │       │   └── wordlist/
│   │       │       ├── chinese_simplified.txt
│   │       │       ├── chinese_traditional.txt
│   │       │       ├── czech.txt
│   │       │       ├── english.txt
│   │       │       ├── french.txt
│   │       │       ├── italian.txt
│   │       │       ├── japanese.txt
│   │       │       ├── korean.txt
│   │       │       ├── portuguese.txt
│   │       │       ├── russian.txt
│   │       │       ├── spanish.txt
│   │       │       └── turkish.txt
│   │       ├── simplelogger.properties
│   │       └── unused/
│   │           ├── calc_addrs.cl
│   │           ├── calc_addrs_fix_zero.cl
│   │           └── gpu.cl
│   └── test/
│       ├── java/
│       │   └── net/
│       │       └── ladenthin/
│       │           └── bitcoinaddressfinder/
│       │               ├── AbstractPlaintextFileTest.java
│       │               ├── AbstractProducerTest.java
│       │               ├── AbstractProducerTestImpl.java
│       │               ├── AddressFileTest.java
│       │               ├── AddressFilesToLMDBTest.java
│       │               ├── AddressFormatNotAcceptedExceptionTest.java
│       │               ├── AddressToCoinTest.java
│       │               ├── AddressTxtLineTest.java
│       │               ├── AddressTypeTest.java
│       │               ├── AwaitTimeTest.java
│       │               ├── AwaitTimeTests.java
│       │               ├── BIP39DataProvider.java
│       │               ├── BIP39KeyProducerTest.java
│       │               ├── BIP39WordlistTest.java
│       │               ├── Base36DecoderTest.java
│       │               ├── Bech32HelperTest.java
│       │               ├── BitHelperTest.java
│       │               ├── ByteBufferUtilityTest.java
│       │               ├── ByteConversionTest.java
│       │               ├── CommonDataProvider.java
│       │               ├── ConsumerJavaTest.java
│       │               ├── EndiannessConverterTest.java
│       │               ├── EqualHashCodeToStringTestHelper.java
│       │               ├── FileHelperTest.java
│       │               ├── FinderTest.java
│       │               ├── HexEncodeTest.java
│       │               ├── KeyUtilityTest.java
│       │               ├── LMDBBase.java
│       │               ├── LMDBPersistencePerformanceTest.java
│       │               ├── LMDBPersistenceTest.java
│       │               ├── LMDBPlatformAssume.java
│       │               ├── LMDBToAddressFileTest.java
│       │               ├── LogLevelChange.java
│       │               ├── MainTest.java
│       │               ├── ManualDebugConstants.java
│       │               ├── MockConsumer.java
│       │               ├── MockKeyProducer.java
│       │               ├── MockKeyProducerTest.java
│       │               ├── NetworkParameterFactoryTest.java
│       │               ├── OpenCLBuilderTest.java
│       │               ├── OpenCLContextTest.java
│       │               ├── OpenCLDeviceTest.java
│       │               ├── OpenCLGridResultTest.java
│       │               ├── OpenCLPlatformAssume.java
│       │               ├── OpenCLPlatformSelectorTest.java
│       │               ├── OpenCLPlatformTest.java
│       │               ├── OpenCLTest.java
│       │               ├── PlatformAssume.java
│       │               ├── PrivateKeyTooLargeExceptionTest.java
│       │               ├── PrivateKeyValidatorTest.java
│       │               ├── ProbeAddressesOpenCLTest.java
│       │               ├── ProducerJavaSecretsFilesTest.java
│       │               ├── ProducerJavaTest.java
│       │               ├── ProducerOpenCLTest.java
│       │               ├── ProducerStateTest.java
│       │               ├── PublicKeyBytesTest.java
│       │               ├── RandomSecretSupplierTest.java
│       │               ├── ReadStatisticTest.java
│       │               ├── SecretsFileTest.java
│       │               ├── SeparatorFormatTest.java
│       │               ├── StatisticsTest.java
│       │               ├── ToStringTest.java
│       │               ├── configuration/
│       │               │   ├── CKeyProducerJavaIncrementalTest.java
│       │               │   ├── CProducerTest.java
│       │               │   └── UnknownSecretFormatExceptionTest.java
│       │               ├── eckey/
│       │               │   └── Secp256k1Test.java
│       │               ├── keyproducer/
│       │               │   ├── AbstractKeyProducerQueueBufferedTest.java
│       │               │   ├── ConnectionUtilsTest.java
│       │               │   ├── KeyProducerIdIsNotUniqueExceptionTest.java
│       │               │   ├── KeyProducerIdNullExceptionTest.java
│       │               │   ├── KeyProducerIdUnknownExceptionTest.java
│       │               │   ├── KeyProducerJavaBip39Test.java
│       │               │   ├── KeyProducerJavaIncrementalTest.java
│       │               │   ├── KeyProducerJavaRandomTest.java
│       │               │   ├── KeyProducerJavaSocketTest.java
│       │               │   ├── KeyProducerJavaTest.java
│       │               │   ├── KeyProducerJavaWebSocketTest.java
│       │               │   ├── KeyProducerJavaZmqTest.java
│       │               │   ├── KeyProducerTestUtility.java
│       │               │   ├── NoMoreSecretsAvailableExceptionTest.java
│       │               │   └── TestTimeProvider.java
│       │               ├── persistence/
│       │               │   └── PersistenceUtilsTest.java
│       │               └── staticaddresses/
│       │                   ├── AbstractTestAddresses.java
│       │                   ├── AddressesFileSpecialUsecases.java
│       │                   ├── AddressesFiles.java
│       │                   ├── StaticAddressesFiles.java
│       │                   ├── StaticKey.java
│       │                   ├── TestAddresses.java
│       │                   ├── TestAddresses1337.java
│       │                   ├── TestAddresses42.java
│       │                   ├── TestAddressesFiles.java
│       │                   ├── TestAddressesLMDB.java
│       │                   └── enums/
│       │                       ├── P2PKH.java
│       │                       ├── P2SH.java
│       │                       ├── P2WPKH.java
│       │                       ├── PublicAddress.java
│       │                       └── StaticUnsupportedAddress.java
│       └── resources/
│           ├── testOpenCLInfo/
│           │   ├── config_OpenCLInfo.js
│           │   ├── config_OpenCLInfo.json
│           │   ├── config_OpenCLInfo.yaml
│           │   └── config_OpenCLInfo.yml
│           ├── testRoundtrip/
│           │   ├── addresses/
│           │   │   ├── fileContainingAddresses0.txt
│           │   │   ├── fileContainingAddresses1.tsv
│           │   │   └── fileContainingAddresses2.csv
│           │   ├── config_AddressFilesToLMDB.json
│           │   ├── config_Find_1OpenCLDevice.json
│           │   ├── config_Find_SecretsFile.json
│           │   ├── config_LMDBToAddressFile.json
│           │   └── secrets/
│           │       ├── fileContainingSecrets_BIG_INTEGER.txt
│           │       ├── fileContainingSecrets_DUMPED_RIVATE_KEY.txt
│           │       ├── fileContainingSecrets_SHA256.txt
│           │       └── fileContainingSecrets_STRING_DO_SHA256.txt
│           └── vectors.json
├── testAddressTxtLineTest.bat
└── update.bat
Download .txt
SYMBOL INDEX (1528 symbols across 192 files)

FILE: helper/bitinfocharts_com_scraping/scraping.py
  function findAllInSource (line 23) | def findAllInSource(addressPattern, driver):
  function getAllUrls (line 27) | def getAllUrls(urlPattern):
  function scrapeAddresses (line 37) | def scrapeAddresses(urlPattern, addressPattern, driver):
  function writeToFile (line 47) | def writeToFile(addressSet, filename):

FILE: helper/dumpwallet/dumpwallet.py
  function getBetween (line 34) | def getBetween(start, end, s):

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/AbstractPlaintextFile.java
  class AbstractPlaintextFile (line 29) | public abstract class AbstractPlaintextFile implements Interruptable {
    method AbstractPlaintextFile (line 38) | public AbstractPlaintextFile(@NonNull File file, @NonNull ReadStatisti...
    method calculateFileProgress (line 43) | protected double calculateFileProgress(@NonNull RandomAccessFile raf) ...
    method processLine (line 47) | protected abstract void processLine(String line);
    method readFile (line 49) | public void readFile() throws IOException {
    method interrupt (line 72) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/AbstractProducer.java
  class AbstractProducer (line 31) | public abstract class AbstractProducer implements Producer {
    method AbstractProducer (line 50) | public AbstractProducer(CProducer cProducer, Consumer consumer, KeyUti...
    method initProducer (line 59) | @Override
    method releaseProducer (line 65) | @Override
    method run (line 70) | @Override
    method produceKeys (line 95) | @Override
    method consumeSecrets (line 126) | void consumeSecrets(BigInteger[] secrets) {
    method logErrorInProduceKeys (line 141) | protected void logErrorInProduceKeys(Throwable e, BigInteger secret) {
    method logErrorInProduceKeys (line 145) | protected void logErrorInProduceKeys(Exception e) {
    method logNoMoreSecretsInSecretFactory (line 149) | protected void logNoMoreSecretsInSecretFactory() {
    method waitTillProducerNotRunning (line 153) | @Override
    method createSecretBase (line 163) | public BigInteger createSecretBase(BigInteger secret, boolean logSecre...
    method calculateSecretKey (line 182) | public static BigInteger calculateSecretKey(BigInteger secretBase, int...
    method getLogger (line 190) | Logger getLogger() {
    method setLogger (line 194) | void setLogger(Logger logger) {
    method interrupt (line 198) | @Override
    method getState (line 203) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/AddressFile.java
  class AddressFile (line 26) | public class AddressFile extends AbstractPlaintextFile {
    method AddressFile (line 37) | public AddressFile(@NonNull File file, ReadStatistic readStatistic, @N...
    method processLine (line 45) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/AddressFilesToLMDB.java
  class AddressFilesToLMDB (line 39) | public class AddressFilesToLMDB implements Runnable, Interruptable {
    method AddressFilesToLMDB (line 56) | public AddressFilesToLMDB( @NonNull CAddressFilesToLMDB addressFilesTo...
    method run (line 60) | @Override
    method logProgress (line 128) | private void logProgress() {
    method interrupt (line 132) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/AddressFormatNotAcceptedException.java
  class AddressFormatNotAcceptedException (line 27) | public class AddressFormatNotAcceptedException extends Exception {
    method AddressFormatNotAcceptedException (line 31) | public AddressFormatNotAcceptedException(String reason) {
    method getReason (line 36) | public String getReason() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/AddressToCoin.java
  method toString (line 38) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/AddressTxtLine.java
  class AddressTxtLine (line 37) | public class AddressTxtLine {
    method fromLine (line 107) | @NonNull
    method parseBase58Address (line 230) | static AddressToCoin parseBase58Address(String base58, int versionByte...
    method getCoinIfPossible (line 291) | @NonNull

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/AddressType.java
  type AddressType (line 25) | public enum AddressType {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/BIP39KeyProducer.java
  class BIP39KeyProducer (line 38) | public class BIP39KeyProducer extends java.util.Random {
    method BIP39KeyProducer (line 46) | public BIP39KeyProducer(String mnemonic, String passphrase, String bip...
    method nextKey (line 56) | public DeterministicKey nextKey() throws NoMoreSecretsAvailableExcepti...
    method append (line 65) | public static List<ChildNumber> append(List<ChildNumber> base, ChildNu...
    method nextBytes (line 74) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/BIP39Wordlist.java
  type BIP39Wordlist (line 23) | public enum BIP39Wordlist {
    method BIP39Wordlist (line 64) | BIP39Wordlist(String fileName) {
    method getWordListStream (line 81) | public InputStream getWordListStream() {
    method fromLanguageName (line 106) | public static BIP39Wordlist fromLanguageName(String name) {
    method getSeparator (line 118) | public String getSeparator() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/Base36Decoder.java
  class Base36Decoder (line 23) | public class Base36Decoder {
    method decodeBase36ToFixedLengthBytes (line 39) | public byte[] decodeBase36ToFixedLengthBytes(String base36Encoded, fin...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/Bech32Helper.java
  class Bech32Helper (line 29) | public class Bech32Helper {
    method decodeBech32CharsetToValues (line 61) | public byte[] decodeBech32CharsetToValues(String base32String) {
    method decode5to8 (line 80) | private byte[] decode5to8(byte[] bytes) throws ReflectiveOperationExce...
    method decode5to8WithPadding (line 84) | private byte[] decode5to8WithPadding(byte[] bytes) throws ReflectiveOp...
    method encode8to5 (line 88) | private byte[] encode8to5(byte[] data) throws ReflectiveOperationExcep...
    method invokeConvertBitsStatic (line 92) | @SuppressWarnings("unchecked")
    method extractPKHFromBitcoinCashAddress (line 119) | public byte[] extractPKHFromBitcoinCashAddress(String address) throws ...
    method getWitnessPrograms (line 140) | public byte[] getWitnessPrograms(Bech32.Bech32Data bechData) throws Re...
    method getWitnessVersion (line 157) | public Short getWitnessVersion(Bech32.Bech32Data bechData) throws Refl...
    method invokeProtectedMethod (line 161) | @SuppressWarnings("unchecked")

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/BitHelper.java
  class BitHelper (line 23) | public class BitHelper {
    method convertBitsToSize (line 27) | public int convertBitsToSize(int bits) {
    method getKillBits (line 31) | public BigInteger getKillBits(int bits) {
    method assertBatchSizeInBitsIsInRange (line 35) | public void assertBatchSizeInBitsIsInRange(int batchSizeInBits) {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ByteBufferUtility.java
  class ByteBufferUtility (line 29) | public class ByteBufferUtility {
    method ByteBufferUtility (line 36) | public ByteBufferUtility(boolean allocateDirect) {
    method freeByteBuffer (line 48) | public void freeByteBuffer(@Nullable ByteBuffer byteBuffer) {
    method byteBufferToBytes (line 65) | public byte[] byteBufferToBytes(ByteBuffer byteBuffer) {
    method byteArrayToByteBuffer (line 72) | public ByteBuffer byteArrayToByteBuffer(byte[] bytes) {
    method byteArrayToByteBufferWrapped (line 80) | private ByteBuffer byteArrayToByteBufferWrapped(byte[] bytes) {
    method byteArrayToByteBufferAllocatedDirect (line 86) | private ByteBuffer byteArrayToByteBufferAllocatedDirect(byte[] bytes) {
    method putToByteBuffer (line 98) | public static void putToByteBuffer(ByteBuffer buffer, byte[] byteArray) {
    method getHexFromByteBuffer (line 106) | public String getHexFromByteBuffer(ByteBuffer byteBuffer) {
    method getByteBufferFromHex (line 112) | public ByteBuffer getByteBufferFromHex(String hex) {
    method ensureByteBufferCapacityFitsInt (line 128) | public static int ensureByteBufferCapacityFitsInt(long capacity) {
    method allocateByteBufferDirectStrict (line 151) | public ByteBuffer allocateByteBufferDirectStrict(int capacity) {
    method bigIntegerToBytes (line 169) | public static byte[] bigIntegerToBytes(final BigInteger bigInteger) {
    method reverse (line 182) | public void reverse(byte @NonNull [] array) {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ByteConversion.java
  class ByteConversion (line 21) | public class ByteConversion {
    method mibToBytes (line 23) | public long mibToBytes(long mib) {
    method bytesToMib (line 27) | public double bytesToMib(long bytes) {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/Consumer.java
  type Consumer (line 21) | public interface Consumer extends Interruptable {
    method consumeKeys (line 23) | void consumeKeys(PublicKeyBytes[] publicKeyBytes) throws InterruptedEx...
    method startConsumer (line 25) | void startConsumer();

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ConsumerJava.java
  class ConsumerJava (line 48) | public class ConsumerJava implements Consumer {
    method ConsumerJava (line 91) | protected ConsumerJava(CConsumerJava consumerJava, KeyUtility keyUtili...
    method getLogger (line 104) | Logger getLogger() {
    method setLogger (line 108) | void setLogger(Logger logger) {
    method initLMDB (line 112) | protected void initLMDB() {
    method startStatisticsTimer (line 117) | protected void startStatisticsTimer() {
    method startConsumer (line 136) | @Override
    method consumeKeysRunner (line 152) | private void consumeKeysRunner() {
    method consumeKeys (line 179) | void consumeKeys(ByteBuffer threadLocalReuseableByteBuffer) throws Mne...
    method containsAddress (line 257) | public boolean containsAddress(ByteBuffer threadLocalReuseableByteBuff...
    method safeLog (line 283) | private void safeLog(PublicKeyBytes publicKeyBytes, byte[] hash160Unco...
    method containsAddress (line 291) | private boolean containsAddress(ByteBuffer hash160AsByteBuffer) {
    method consumeKeys (line 309) | @Override
    method interrupt (line 334) | @Override
    method keysQueueSize (line 362) | @VisibleForTesting
    method toString (line 367) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/EndiannessConverter.java
  class EndiannessConverter (line 30) | public class EndiannessConverter {
    method EndiannessConverter (line 46) | EndiannessConverter(ByteOrder sourceOrder, ByteOrder targetOrder, Byte...
    method convertEndian (line 58) | public void convertEndian(byte[] array) {
    method mustConvert (line 69) | public boolean mustConvert() {
    method getSourceOrder (line 73) | public ByteOrder getSourceOrder() {
    method getTargetOrder (line 77) | public ByteOrder getTargetOrder() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/FileHelper.java
  class FileHelper (line 27) | public class FileHelper {
    method stringsToFiles (line 31) | public List<File> stringsToFiles(List<String> strings) {
    method assertFilesExists (line 39) | public void assertFilesExists(List<File> files) throws IllegalArgument...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/Finder.java
  class Finder (line 50) | public class Finder implements Interruptable {
    method Finder (line 79) | public Finder(CFinder finder) {
    method startKeyProducer (line 83) | public void startKeyProducer() {
    method processKeyProducers (line 128) | private <T, K> void processKeyProducers(
    method startConsumer (line 149) | public void startConsumer() {
    method configureProducer (line 159) | public void configureProducer() {
    method processProducers (line 187) | private <T extends CProducer, P> void processProducers(
    method getKeyProducer (line 204) | public KeyProducer getKeyProducer(CProducer cProducer) throws RuntimeE...
    method initProducer (line 212) | public void initProducer() {
    method startProducer (line 219) | public void startProducer() {
    method shutdownAndAwaitTermination (line 226) | public void shutdownAndAwaitTermination() {
    method interrupt (line 244) | @Override
    method getKeyProducers (line 268) | public Map<String, KeyProducer> getKeyProducers() {
    method getAllProducers (line 272) | public List<Producer> getAllProducers() {
    method freeAllProducers (line 280) | public void freeAllProducers() {
    method freeAllKeyProducers (line 286) | public void freeAllKeyProducers() {
    method getAllConsumers (line 290) | public List<Consumer> getAllConsumers() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/Interruptable.java
  type Interruptable (line 21) | public interface Interruptable {
    method interrupt (line 22) | void interrupt();

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/KeyUtility.java
  method killBits (line 45) | public BigInteger killBits(BigInteger bigInteger, BigInteger killBits) {
  method getHash160ByteBufferFromBase58String (line 53) | public ByteBuffer getHash160ByteBufferFromBase58String(String base58) {
  method toBase58 (line 59) | public String toBase58(byte[] hash160) {
  method createSecret (line 64) | public BigInteger createSecret(int maximumBitLength, Random random) {
  method createECKey (line 69) | public ECKey createECKey(BigInteger bi, boolean compressed) {
  method createKeyDetails (line 73) | public String createKeyDetails(ECKey key) throws MnemonicException.Mnemo...
  method createMnemonics (line 97) | public String createMnemonics(byte[] privateKeyBytes) {
  method addressToByteBuffer (line 123) | public ByteBuffer addressToByteBuffer(LegacyAddress address) {
  method byteBufferToAddress (line 131) | public LegacyAddress byteBufferToAddress(ByteBuffer byteBuffer) {
  method createSecrets (line 136) | public BigInteger[] createSecrets(int overallWorkSize, boolean returnSta...
  method byteArrayToInt (line 145) | @Deprecated
  method byteArrayToInt (line 150) | @Deprecated
  method byteArrayToIntArray (line 158) | @Deprecated
  method intToByteArray (line 163) | @Deprecated
  method intToByteArray (line 170) | @Deprecated
  method swapIntBytes (line 178) | @Deprecated
  method bigIntegerToFixedLengthHex (line 202) | public String bigIntegerToFixedLengthHex(BigInteger value) {
  method bigIntegerFromUnsignedByteArray (line 220) | public BigInteger bigIntegerFromUnsignedByteArray(byte[] buffer) {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/LMDBToAddressFile.java
  class LMDBToAddressFile (line 33) | public class LMDBToAddressFile implements Runnable, Interruptable {
    method LMDBToAddressFile (line 43) | public LMDBToAddressFile(CLMDBToAddressFile lmdbToAddressFile) {
    method run (line 47) | @Override
    method interrupt (line 66) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/NetworkParameterFactory.java
  class NetworkParameterFactory (line 25) | public class NetworkParameterFactory {
    method getNetwork (line 27) | public Network getNetwork() {
    method getNetworkParameters (line 31) | private NetworkParameters getNetworkParameters() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/OpenCLContext.java
  class OpenCLContext (line 60) | public class OpenCLContext implements ReleaseCLObject {
    method getOpenCLPrograms (line 64) | public String[] getOpenCLPrograms() throws IOException {
    method getResourceNames (line 76) | private List<String> getResourceNames() {
    method OpenCLContext (line 112) | public OpenCLContext(CProducerOpenCL producerOpenCL, BitHelper bitHelp...
    method OpenCLContext (line 116) | @VisibleForTesting
    method init (line 123) | public void init() throws IOException {
    method getOpenClTask (line 167) | @Nullable
    method isClosed (line 172) | @Override
    method close (line 177) | @Override
    method createKeys (line 204) | public OpenCLGridResult createKeys(BigInteger privateKeyBase) {
    method getResourceNamesContent (line 216) | private static List<String> getResourceNamesContent(List<String> resou...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/OpenCLGridResult.java
  class OpenCLGridResult (line 26) | public class OpenCLGridResult {
    method OpenCLGridResult (line 45) | OpenCLGridResult(BigInteger secretKeyBase, int workSize, ByteBuffer re...
    method getSecretKeyBase (line 51) | public BigInteger getSecretKeyBase() {
    method getWorkSize (line 55) | public int getWorkSize() {
    method getResult (line 59) | public ByteBuffer getResult() {
    method getPublicKeyBytes (line 83) | public PublicKeyBytes[] getPublicKeyBytes() {
    method trimU32PrefixBytes (line 94) | public static byte[] trimU32PrefixBytes(byte[] fullArray) {
    method getPublicKeyFromByteBufferXY (line 125) | private static final PublicKeyBytes getPublicKeyFromByteBufferXY(ByteB...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/OpenClTask.java
  class OpenClTask (line 47) | public class OpenClTask implements ReleaseCLObject {
    class CLByteBufferPointerArgument (line 66) | public abstract static class CLByteBufferPointerArgument implements Re...
      method CLByteBufferPointerArgument (line 93) | public CLByteBufferPointerArgument(ByteBuffer byteBuffer, Pointer ho...
      method getByteBuffer (line 100) | public ByteBuffer getByteBuffer() {
      method getHostMemoryPointer (line 105) | public Pointer getHostMemoryPointer() {
      method getClMemPointer (line 110) | public Pointer getClMemPointer() {
      method getMem (line 114) | public cl_mem getMem() {
      method isClosed (line 118) | @Override
      method close (line 123) | @Override
    class DestinationArgument (line 132) | public static class DestinationArgument extends CLByteBufferPointerArg...
      method DestinationArgument (line 134) | private DestinationArgument(ByteBuffer byteBuffer, Pointer hostMemor...
      method create (line 138) | public static DestinationArgument create(cl_context context, long si...
    class SourceArgument (line 155) | public static class SourceArgument extends CLByteBufferPointerArgument {
      method SourceArgument (line 157) | private SourceArgument(ByteBuffer byteBuffer, Pointer hostMemoryPoin...
      method create (line 161) | public static SourceArgument create(cl_context context, long sizeInB...
    method OpenClTask (line 171) | public OpenClTask(cl_context context, CProducerOpenCL cProducer, BitHe...
    method getDstSizeInBytes (line 181) | public long getDstSizeInBytes() {
    method setSrcPrivateKeyChunk (line 203) | public void setSrcPrivateKeyChunk(BigInteger privateKeyBase) {
    method getPrivateKeySourceArgument (line 217) | @VisibleForTesting
    method executeKernel (line 222) | public ByteBuffer executeKernel(cl_kernel kernel, cl_command_queue com...
    method isClosed (line 313) | @Override
    method close (line 318) | @Override
    method cloneByteBuffer (line 330) | private static ByteBuffer cloneByteBuffer(final ByteBuffer original) {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/PrivateKeyTooLargeException.java
  class PrivateKeyTooLargeException (line 30) | public class PrivateKeyTooLargeException extends IllegalArgumentException {
    method PrivateKeyTooLargeException (line 36) | public PrivateKeyTooLargeException(BigInteger providedKey, BigInteger ...
    method buildMessage (line 43) | private static String buildMessage(BigInteger providedKey, BigInteger ...
    method getProvidedKey (line 51) | public BigInteger getProvidedKey() {
    method getMaxAllowedKey (line 55) | public BigInteger getMaxAllowedKey() {
    method getBatchSizeInBits (line 59) | public int getBatchSizeInBits() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/PrivateKeyValidator.java
  class PrivateKeyValidator (line 32) | public class PrivateKeyValidator {
    method getMaxPrivateKeyForBatchSize (line 47) | public BigInteger getMaxPrivateKeyForBatchSize(int batchSizeInBits) {
    method isInvalidWithBatchSize (line 72) | public boolean isInvalidWithBatchSize(@NonNull BigInteger privateKeyBa...
    method isOutsidePrivateKeyRange (line 84) | public boolean isOutsidePrivateKeyRange(@NonNull BigInteger secret) {
    method returnValidPrivateKey (line 98) | public @NonNull BigInteger returnValidPrivateKey(@NonNull BigInteger s...
    method replaceInvalidPrivateKeys (line 113) | public void replaceInvalidPrivateKeys(@NonNull BigInteger[] secrets) {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/Producer.java
  type Producer (line 24) | public interface Producer extends Runnable, Interruptable, ProducerState...
    method initProducer (line 30) | void initProducer();
    method releaseProducer (line 35) | void releaseProducer();
    method produceKeys (line 43) | void produceKeys() throws Exception;
    method processSecretBase (line 51) | void processSecretBase(BigInteger secretBase);
    method processSecrets (line 58) | void processSecrets(BigInteger[] secrets);
    method waitTillProducerNotRunning (line 63) | void waitTillProducerNotRunning();

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerJava.java
  class ProducerJava (line 25) | public class ProducerJava extends AbstractProducer {
    method ProducerJava (line 29) | public ProducerJava(CProducerJava producerJava, Consumer consumer, Key...
    method processSecretBase (line 34) | @Override
    method processSecrets (line 44) | @Override
    method createGrid (line 57) | protected PublicKeyBytes[] createGrid(final BigInteger secretBase) {
    method toString (line 71) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerJavaSecretsFiles.java
  class ProducerJavaSecretsFiles (line 33) | public class ProducerJavaSecretsFiles extends ProducerJava {
    method ProducerJavaSecretsFiles (line 46) | public ProducerJavaSecretsFiles(CProducerJavaSecretsFiles producerJava...
    method produceKeys (line 51) | @Override
    method processSecrets (line 86) | @Override
    method logProgress (line 91) | private void logProgress() {
    method interrupt (line 95) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerOpenCL.java
  class ProducerOpenCL (line 32) | public class ProducerOpenCL extends AbstractProducer {
    method ProducerOpenCL (line 42) | public ProducerOpenCL(CProducerOpenCL producerOpenCL, Consumer consume...
    method initProducer (line 54) | @Override
    method processSecretBase (line 65) | @Override
    method processSecrets (line 87) | @Override
    class ResultReaderRunnable (line 92) | protected static class ResultReaderRunnable implements Runnable {
      method ResultReaderRunnable (line 101) | ResultReaderRunnable(OpenCLGridResult openCLGridResult, Consumer con...
      method run (line 108) | @Override
    method waitTillFreeThreadsInPool (line 125) | @VisibleForTesting
    method getFreeThreads (line 133) | @VisibleForTesting
    method releaseProducer (line 138) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerState.java
  type ProducerState (line 21) | public enum ProducerState {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerStateProvider.java
  type ProducerStateProvider (line 21) | public interface ProducerStateProvider {
    method getState (line 22) | ProducerState getState();

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/PublicKeyBytes.java
  class PublicKeyBytes (line 34) | public class PublicKeyBytes {
    method getSecretKey (line 236) | public BigInteger getSecretKey() {
    method getCompressed (line 240) | public byte[] getCompressed() {
    method getUncompressed (line 244) | public byte[] getUncompressed() {
    method isOutsidePrivateKeyRange (line 248) | public boolean isOutsidePrivateKeyRange() {
    method PublicKeyBytes (line 252) | public PublicKeyBytes(BigInteger secretKey, byte[] uncompressed) {
    method PublicKeyBytes (line 256) | public PublicKeyBytes(BigInteger secretKey, byte[] uncompressed, byte[...
    method PublicKeyBytes (line 260) | public PublicKeyBytes(BigInteger secretKey, byte @NonNull [] uncompres...
    method PublicKeyBytes (line 267) | public PublicKeyBytes(BigInteger secretKey, byte @NonNull [] uncompres...
    method fromPrivate (line 276) | public static PublicKeyBytes fromPrivate(BigInteger secretKey) {
    method createCompressedBytes (line 299) | public static byte @NonNull [] createCompressedBytes(byte @NonNull [] ...
    method assembleUncompressedPublicKey (line 335) | public static byte @NonNull [] assembleUncompressedPublicKey(byte @Non...
    method isAllCoordinateBytesZero (line 355) | public static boolean isAllCoordinateBytesZero(byte[] uncompressed) {
    method calculateHash160 (line 364) | private static byte @NonNull [] calculateHash160(byte[] input) {
    method getUncompressedKeyHash (line 372) | public byte @NonNull [] getUncompressedKeyHash() {
    method getCompressedKeyHash (line 379) | public byte @NonNull [] getCompressedKeyHash() {
    method sha256hash160Fast (line 391) | public static byte[] sha256hash160Fast(byte[] input) {
    method getCompressedKeyHashAsBase58 (line 400) | public @NonNull String getCompressedKeyHashAsBase58(@NonNull KeyUtilit...
    method getUncompressedKeyHashAsBase58 (line 407) | public @NonNull String getUncompressedKeyHashAsBase58(@NonNull KeyUtil...
    method runtimePublicKeyCalculationCheck (line 414) | public boolean runtimePublicKeyCalculationCheck(Logger logger) {
    method hashCode (line 466) | @Override
    method equals (line 474) | @Override
    method toString (line 490) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/RandomSecretSupplier.java
  class RandomSecretSupplier (line 24) | public class RandomSecretSupplier implements SecretSupplier {
    method RandomSecretSupplier (line 27) | public RandomSecretSupplier(Random random) {
    method nextSecret (line 31) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ReadStatistic.java
  class ReadStatistic (line 26) | public class ReadStatistic {
    method incrementUnsupported (line 43) | public void incrementUnsupported(String reason) {
    method getUnsupportedTotal (line 52) | public long getUnsupportedTotal() {
    method toString (line 56) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/ReleaseCLObject.java
  type ReleaseCLObject (line 42) | public interface ReleaseCLObject extends AutoCloseable {
    method isClosed (line 50) | boolean isClosed();
    method close (line 61) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/SecretSupplier.java
  type SecretSupplier (line 24) | @FunctionalInterface
    method nextSecret (line 26) | BigInteger nextSecret(int bitLength) throws NoMoreSecretsAvailableExce...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/SecretsFile.java
  class SecretsFile (line 33) | public class SecretsFile extends AbstractPlaintextFile {
    method SecretsFile (line 39) | public SecretsFile(@NonNull Network network, @NonNull File file, @NonN...
    method processLine (line 46) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/SeparatorFormat.java
  type SeparatorFormat (line 27) | public enum SeparatorFormat {
    method SeparatorFormat (line 116) | SeparatorFormat(String symbol) {
    method getSymbol (line 120) | public String getSymbol() {
    method getSortedSeparators (line 135) | public static List<SeparatorFormat> getSortedSeparators() {
    method split (line 161) | public static String[] split(String input) {
    method splitRecursive (line 179) | private static void splitRecursive(String input, List<String> result, ...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/Shutdown.java
  type Shutdown (line 21) | public interface Shutdown {
    method shutdown (line 22) | void shutdown();

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/Statistics.java
  class Statistics (line 21) | public class Statistics {
    method createStatisticsMessage (line 26) | String createStatisticsMessage(long uptime, long keys, long keysSumOfT...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/cli/Main.java
  class Main (line 46) | public class Main implements Runnable, Interruptable {
    method Main (line 85) | public Main(CConfiguration configuration) {
    method readString (line 89) | public static String readString(Path path) {
    method fromJson (line 98) | public static CConfiguration fromJson(String configurationString) {
    method fromYaml (line 107) | public static CConfiguration fromYaml(String configurationString) {
    method configurationToJson (line 116) | public static String configurationToJson(CConfiguration configuration) {
    method configurationToYAML (line 126) | public static String configurationToYAML(CConfiguration configuration) {
    method main (line 135) | public static void main(String[] args) {
    method logConfigurationTransformation (line 156) | public void logConfigurationTransformation() {
    method run (line 171) | @Override
    method printAllStackTracesWithDelay (line 222) | public static void printAllStackTracesWithDelay(long delayMillis, bool...
    method addSchutdownHook (line 253) | private void addSchutdownHook() {
    method interrupt (line 267) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CAddressFileOutputFormat.java
  type CAddressFileOutputFormat (line 21) | public enum CAddressFileOutputFormat {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CAddressFilesToLMDB.java
  class CAddressFilesToLMDB (line 26) | public class CAddressFilesToLMDB {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CCommand.java
  type CCommand (line 21) | public enum CCommand {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CConfiguration.java
  class CConfiguration (line 23) | public class CConfiguration {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CConsumerJava.java
  class CConsumerJava (line 24) | public class CConsumerJava {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CFinder.java
  class CFinder (line 26) | public class CFinder {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJava.java
  class CKeyProducerJava (line 24) | public class CKeyProducerJava {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaBip39.java
  class CKeyProducerJavaBip39 (line 25) | public class CKeyProducerJavaBip39 extends CKeyProducerJava {
    method getCreationTimeInstant (line 81) | public Instant getCreationTimeInstant() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaIncremental.java
  class CKeyProducerJavaIncremental (line 25) | public class CKeyProducerJavaIncremental extends CKeyProducerJava {
    method getStartAddress (line 30) | public BigInteger getStartAddress() {
    method getEndAddress (line 34) | public BigInteger getEndAddress() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaRandom.java
  class CKeyProducerJavaRandom (line 23) | public class CKeyProducerJavaRandom extends CKeyProducerJava {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaRandomInstance.java
  type CKeyProducerJavaRandomInstance (line 31) | public enum CKeyProducerJavaRandomInstance {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaReceiver.java
  class CKeyProducerJavaReceiver (line 21) | public class CKeyProducerJavaReceiver extends CKeyProducerJava {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaSocket.java
  class CKeyProducerJavaSocket (line 21) | public class CKeyProducerJavaSocket extends CKeyProducerJavaReceiver {
    type Mode (line 23) | public enum Mode {
    method getHost (line 58) | public String getHost() {
    method getPort (line 62) | public int getPort() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaWebSocket.java
  class CKeyProducerJavaWebSocket (line 21) | public class CKeyProducerJavaWebSocket extends CKeyProducerJavaReceiver {
    method getPort (line 25) | public int getPort() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaZmq.java
  class CKeyProducerJavaZmq (line 21) | public class CKeyProducerJavaZmq extends CKeyProducerJavaReceiver {
    type Mode (line 23) | public enum Mode {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CLMDBConfigurationReadOnly.java
  class CLMDBConfigurationReadOnly (line 21) | public class CLMDBConfigurationReadOnly {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CLMDBConfigurationWrite.java
  class CLMDBConfigurationWrite (line 23) | public class CLMDBConfigurationWrite extends CLMDBConfigurationReadOnly {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CLMDBToAddressFile.java
  class CLMDBToAddressFile (line 21) | public class CLMDBToAddressFile {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CProducer.java
  class CProducer (line 25) | public class CProducer {
    method getOverallWorkSize (line 49) | public int getOverallWorkSize(BitHelper bitHelper) {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CProducerJava.java
  class CProducerJava (line 21) | public class CProducerJava extends CProducer {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CProducerJavaSecretsFiles.java
  class CProducerJavaSecretsFiles (line 24) | public class CProducerJavaSecretsFiles extends CProducerJava {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CProducerOpenCL.java
  class CProducerOpenCL (line 23) | public class CProducerOpenCL extends CProducer {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CSecretFormat.java
  type CSecretFormat (line 21) | public enum CSecretFormat {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/UnknownSecretFormatException.java
  class UnknownSecretFormatException (line 28) | public class UnknownSecretFormatException extends IllegalArgumentExcepti...
    method UnknownSecretFormatException (line 32) | public UnknownSecretFormatException(CSecretFormat secretFormat) {
    method getSecretFormat (line 37) | public CSecretFormat getSecretFormat() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/eckey/Secp256k1.java
  class Secp256k1 (line 16) | public class Secp256k1 {
    method byteArrayToHexString (line 21) | public static String byteArrayToHexString(byte[] a) {
    method hexStringToByteArray (line 29) | public static byte[] hexStringToByteArray(String s) {
    method doublePoint (line 42) | private static ECPoint doublePoint(final BigInteger p, final BigIntege...
    method addPoint (line 54) | private static ECPoint addPoint(final BigInteger p, final BigInteger a...
    method scalmultNew (line 75) | public static ECPoint scalmultNew(final ECParameterSpec params, final ...
    method scalmultOrg (line 105) | public static ECPoint scalmultOrg(final EllipticCurve curve, final ECP...
    method getPublicKey (line 137) | public static ECPublicKey getPublicKey(final ECPrivateKey pk) throws G...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/AbstractKeyProducer.java
  class AbstractKeyProducer (line 21) | public abstract class AbstractKeyProducer implements KeyProducer {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/AbstractKeyProducerQueueBuffered.java
  class AbstractKeyProducerQueueBuffered (line 34) | public abstract class AbstractKeyProducerQueueBuffered<T extends CKeyPro...
    method AbstractKeyProducerQueueBuffered (line 40) | public AbstractKeyProducerQueueBuffered(T config, KeyUtility keyUtilit...
    method AbstractKeyProducerQueueBuffered (line 46) | protected AbstractKeyProducerQueueBuffered(
    method createSecrets (line 57) | @Override
    method sleep (line 95) | protected void sleep(int millis) {
    method addSecret (line 106) | protected void addSecret(byte[] secret) {
    method getReadTimeout (line 117) | protected abstract int getReadTimeout();

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/ConnectionUtils.java
  class ConnectionUtils (line 24) | public class ConnectionUtils {
    method waitUntilTcpPortOpen (line 26) | public static void waitUntilTcpPortOpen(String host, int port, int tim...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducer.java
  type KeyProducer (line 25) | public interface KeyProducer extends Interruptable {
    method createSecrets (line 26) | BigInteger[] createSecrets(int overallWorkSize, boolean returnStartSec...
    method getLogger (line 27) | Logger getLogger();

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerIdIsNotUniqueException.java
  class KeyProducerIdIsNotUniqueException (line 27) | public class KeyProducerIdIsNotUniqueException extends RuntimeException {
    method KeyProducerIdIsNotUniqueException (line 31) | public KeyProducerIdIsNotUniqueException(String id) {
    method getId (line 36) | public String getId() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerIdNullException.java
  class KeyProducerIdNullException (line 27) | public class KeyProducerIdNullException extends RuntimeException {
    method KeyProducerIdNullException (line 29) | public KeyProducerIdNullException() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerIdUnknownException.java
  class KeyProducerIdUnknownException (line 29) | public class KeyProducerIdUnknownException extends RuntimeException {
    method KeyProducerIdUnknownException (line 33) | public KeyProducerIdUnknownException(@Nullable String id) {
    method getId (line 38) | public @Nullable String getId() {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJava.java
  class KeyProducerJava (line 24) | public abstract class KeyProducerJava<T extends CKeyProducerJava> extend...
    method KeyProducerJava (line 30) | public KeyProducerJava(T cKeyProducerJava, Logger logger) {
    method verifyWorkSize (line 35) | public void verifyWorkSize(int overallWorkSize, int maxWorkSize) throw...
    method getLogger (line 41) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaBip39.java
  class KeyProducerJavaBip39 (line 30) | public class KeyProducerJavaBip39 extends KeyProducerJava<CKeyProducerJa...
    method KeyProducerJavaBip39 (line 37) | public KeyProducerJavaBip39(CKeyProducerJavaBip39 cKeyProducerJavaBip3...
    method createSecrets (line 52) | @Override
    method interrupt (line 58) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaIncremental.java
  class KeyProducerJavaIncremental (line 28) | public class KeyProducerJavaIncremental extends KeyProducerJava<CKeyProd...
    method KeyProducerJavaIncremental (line 33) | public KeyProducerJavaIncremental(CKeyProducerJavaIncremental cKeyProd...
    method createSecrets (line 38) | @Override
    method interrupt (line 62) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaRandom.java
  class KeyProducerJavaRandom (line 32) | public class KeyProducerJavaRandom extends KeyProducerJava<CKeyProducerJ...
    method KeyProducerJavaRandom (line 43) | @SuppressWarnings({"squid:S2245"})
    method createSecrets (line 86) | @Override
    method interrupt (line 92) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaSocket.java
  class KeyProducerJavaSocket (line 36) | public class KeyProducerJavaSocket extends AbstractKeyProducerQueueBuffe...
    method KeyProducerJavaSocket (line 45) | public KeyProducerJavaSocket(CKeyProducerJavaSocket config, KeyUtility...
    method setupSocket (line 50) | private void setupSocket() {
    method closeConnections (line 100) | private void closeConnections() {
    method getReadTimeout (line 109) | @Override
    method interrupt (line 114) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaWebSocket.java
  class KeyProducerJavaWebSocket (line 34) | public class KeyProducerJavaWebSocket extends AbstractKeyProducerQueueBu...
    method KeyProducerJavaWebSocket (line 38) | public KeyProducerJavaWebSocket(CKeyProducerJavaWebSocket config, KeyU...
    method initWebSocketServer (line 43) | private void initWebSocketServer() {
    method getReadTimeout (line 86) | @Override
    method interrupt (line 91) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaZmq.java
  class KeyProducerJavaZmq (line 31) | public class KeyProducerJavaZmq extends AbstractKeyProducerQueueBuffered...
    method KeyProducerJavaZmq (line 37) | public KeyProducerJavaZmq(CKeyProducerJavaZmq config, KeyUtility keyUt...
    method getReadTimeout (line 75) | @Override
    method interrupt (line 80) | @Override

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/NoMoreSecretsAvailableException.java
  class NoMoreSecretsAvailableException (line 28) | public class NoMoreSecretsAvailableException extends RuntimeException {
    method NoMoreSecretsAvailableException (line 30) | public NoMoreSecretsAvailableException() {
    method NoMoreSecretsAvailableException (line 34) | public NoMoreSecretsAvailableException(String message) {
    method NoMoreSecretsAvailableException (line 38) | public NoMoreSecretsAvailableException(String message, Throwable cause) {
    method NoMoreSecretsAvailableException (line 42) | public NoMoreSecretsAvailableException(Throwable cause) {

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLBuilder.java
  class OpenCLBuilder (line 81) | public class OpenCLBuilder {
    method build (line 85) | public List<OpenCLPlatform> build() {
    method createOpenCLDevice (line 126) | private OpenCLDevice createOpenCLDevice(cl_device_id device) {
    method longsToImmutableList (line 207) | private static ImmutableList<@NonNull Long> longsToImmutableList(long[...
    method isOpenCLnativeLibraryLoadable (line 215) | public static boolean isOpenCLnativeLibraryLoadable() {
    method isOneOpenCL2_0OrGreaterDeviceAvailable (line 231) | public static boolean isOneOpenCL2_0OrGreaterDeviceAvailable(List<Open...
    method isOpenCL2_0OrGreater (line 243) | public static boolean isOpenCL2_0OrGreater(ComparableVersion openCLDev...
    method getInt (line 255) | private static int getInt(cl_device_id device, int paramName)
    method getInts (line 268) | private static int[] getInts(cl_device_id device, int paramName, int n...
    method getLong (line 282) | private static long getLong(cl_device_id device, int paramName)
    method getLongs (line 295) | private static long[] getLongs(cl_device_id device, int paramName, int...
    method getString (line 309) | private static String getString(cl_device_id device, int paramName)
    method getString (line 330) | private static String getString(cl_platform_id platform, int paramName)
    method getSize (line 351) | private static long getSize(cl_device_id device, int paramName)
    method getSizes (line 364) | static long[] getSizes(cl_device_id device, int paramName, int numValues)

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLDevice.java
  method getByteOrder (line 119) | public ByteOrder getByteOrder() {
  method toStringPretty (line 126) | public String toStringPretty() {
  method formatWorkItemSizes (line 172) | public static String formatWorkItemSizes(List<Long> sizes) {
  method getDeviceVersionAsComparableVersion (line 182) | public ComparableVersion getDeviceVersionAsComparableVersion() {
  method getComparableVersionFromDeviceVersion (line 186) | public static ComparableVersion getComparableVersionFromDeviceVersion(St...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLPlatform.java
  method OpenCLPlatform (line 43) | public OpenCLPlatform(String platformName, cl_context_properties context...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLPlatformSelector.java
  class OpenCLPlatformSelector (line 23) | public class OpenCLPlatformSelector {
    method select (line 34) | public OpenCLDeviceSelection select(List<OpenCLPlatform> platforms, in...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/persistence/Persistence.java
  type Persistence (line 30) | public interface Persistence extends AutoCloseable {
    method init (line 32) | void init();
    method isClosed (line 33) | boolean isClosed();
    method count (line 34) | long count();
    method getAmount (line 35) | Coin getAmount(ByteBuffer hash160);
    method containsAddress (line 36) | boolean containsAddress(ByteBuffer hash160);
    method writeAllAmountsToAddressFile (line 38) | void writeAllAmountsToAddressFile(File file, CAddressFileOutputFormat ...
    method changeAmount (line 44) | void changeAmount(ByteBuffer hash160, Coin amountToChange);
    method putNewAmount (line 46) | void putNewAmount(ByteBuffer hash160, Coin toWrite);
    method putAllAmounts (line 47) | void putAllAmounts(Map<ByteBuffer, Coin> amounts) throws IOException;
    method getAllAmountsFromAddresses (line 49) | Coin getAllAmountsFromAddresses(List<ByteBuffer> hash160s);
    method getDatabaseSize (line 51) | long getDatabaseSize();
    method increaseDatabaseSize (line 53) | void increaseDatabaseSize(long toIncrease);
    method getIncreasedCounter (line 60) | long getIncreasedCounter();
    method getIncreasedSum (line 67) | long getIncreasedSum();
    method logStats (line 72) | void logStats();

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/persistence/PersistenceUtils.java
  class PersistenceUtils (line 29) | public class PersistenceUtils {
    method PersistenceUtils (line 37) | public PersistenceUtils(Network network) {
    method longToByteBufferDirect (line 41) | public ByteBuffer longToByteBufferDirect(long longValue) {
    method addressListToByteBufferDirect (line 52) | @Deprecated
    method byteBufferToAddressList (line 62) | @Deprecated
    method hashToByteBufferDirect (line 74) | @Deprecated
    method longValueToByteBufferDirectAsReadOnlyBuffer (line 79) | private ByteBuffer longValueToByteBufferDirectAsReadOnlyBuffer(long va...

FILE: src/main/java/net/ladenthin/bitcoinaddressfinder/persistence/lmdb/LMDBPersistence.java
  class LMDBPersistence (line 63) | public class LMDBPersistence implements Persistence {
    method LMDBPersistence (line 81) | public LMDBPersistence(CLMDBConfigurationWrite lmdbConfigurationWrite,...
    method LMDBPersistence (line 88) | public LMDBPersistence(CLMDBConfigurationReadOnly lmdbConfigurationRea...
    method init (line 95) | @Override
    method buildAddressBloomFilter (line 109) | public void buildAddressBloomFilter() {
    method unloadBloomFilter (line 140) | public void unloadBloomFilter() {
    method initReadOnly (line 144) | private void initReadOnly() {
    method initWritable (line 155) | private void initWritable() {
    method getBufferProxyByUseProxyOptimal (line 195) | private BufferProxy<ByteBuffer> getBufferProxyByUseProxyOptimal(boolea...
    method logStatsIfConfigured (line 203) | private void logStatsIfConfigured(boolean onInit) {
    method isLoggingEnabled (line 209) | private boolean isLoggingEnabled(@Nullable CLMDBConfigurationReadOnly ...
    method close (line 213) | @Override
    method isClosed (line 223) | @Override
    method getAmount (line 229) | @Override
    method getCoinFromByteBuffer (line 240) | private Coin getCoinFromByteBuffer(ByteBuffer byteBuffer) {
    method containsAddress (line 247) | @Override
    method writeAllAmountsToAddressFile (line 277) | @Override
    method putAllAmounts (line 318) | @Override
    method changeAmount (line 327) | @Override
    method putNewAmount (line 334) | @Override
    method putNewAmountWithAutoIncrease (line 350) | private void putNewAmountWithAutoIncrease(ByteBuffer hash160, Coin amo...
    method putNewAmountUnsafe (line 367) | private void putNewAmountUnsafe(ByteBuffer hash160, Coin amount) {
    method getAllAmountsFromAddresses (line 386) | @Override
    method count (line 395) | @Override
    method getDatabaseSize (line 411) | @Override
    method increaseDatabaseSize (line 419) | @Override
    method getIncreasedCounter (line 429) | @Override
    method getIncreasedSum (line 434) | @Override
    method logStats (line 439) | @Override
    method getApproximateSizeBytes (line 455) | public static long getApproximateSizeBytes(BloomFilter<?> bloomFilter) {
    method formatSize (line 473) | public static String formatSize(long sizeInBytes) {

FILE: src/main/resources/copyfromhashcat/inc_ecc_secp256k1.h
  type secp256k1_t (line 215) | typedef struct secp256k1

FILE: src/main/resources/copyfromhashcat/inc_hash_ripemd160.h
  type ripemd160_ctx_t (line 65) | typedef struct ripemd160_ctx
  type ripemd160_hmac_ctx_t (line 78) | typedef struct ripemd160_hmac_ctx
  type ripemd160_ctx_vector_t (line 85) | typedef struct ripemd160_ctx_vector
  type ripemd160_hmac_ctx_vector_t (line 98) | typedef struct ripemd160_hmac_ctx_vector

FILE: src/main/resources/copyfromhashcat/inc_hash_sha256.h
  type sha256_ctx_t (line 52) | typedef struct sha256_ctx
  type sha256_hmac_ctx_t (line 65) | typedef struct sha256_hmac_ctx
  type sha256_ctx_vector_t (line 72) | typedef struct sha256_ctx_vector
  type sha256_hmac_ctx_vector_t (line 85) | typedef struct sha256_hmac_ctx_vector

FILE: src/main/resources/copyfromhashcat/inc_types.h
  type uchar (line 41) | typedef unsigned char       uchar;
  type ushort (line 42) | typedef unsigned short      ushort;
  type uint (line 43) | typedef unsigned int        uint;
  type ulong (line 44) | typedef unsigned long       ulong;
  type ullong (line 45) | typedef unsigned long long  ullong;
  type uchar (line 49) | typedef unsigned char  uchar;
  type ushort (line 50) | typedef unsigned short ushort;
  type uint (line 51) | typedef unsigned int   uint;
  type ulong (line 52) | typedef unsigned long  ulong;
  type ulong (line 57) | typedef ulong   ullong;
  type ulong2 (line 58) | typedef ulong2  ullong2;
  type ulong4 (line 59) | typedef ulong4  ullong4;
  type ulong8 (line 60) | typedef ulong8  ullong8;
  type ulong16 (line 61) | typedef ulong16 ullong16;
  type uchar (line 65) | typedef uchar  u8;
  type ushort (line 66) | typedef ushort u16;
  type uint (line 67) | typedef uint   u32;
  type ulong (line 69) | typedef ulong  u64;
  type ullong (line 71) | typedef ullong u64;
  type u8 (line 74) | typedef uint8_t  u8;
  type u16 (line 75) | typedef uint16_t u16;
  type u32 (line 76) | typedef uint32_t u32;
  type u64 (line 77) | typedef uint64_t u64;
  type u8 (line 86) | typedef u8  u8a;
  type u16 (line 87) | typedef u16 u16a;
  type u32 (line 88) | typedef u32 u32a;
  type u64 (line 89) | typedef u64 u64a;
  type u8 (line 101) | typedef u8   u8x;
  type u16 (line 102) | typedef u16  u16x;
  type u32 (line 103) | typedef u32  u32x;
  type u64 (line 104) | typedef u64  u64x;
  function __builtin_align__ (line 126) | struct __device_builtin__ __builtin_align__(2) u8x
  function __builtin_align__ (line 138) | struct __device_builtin__ __builtin_align__(4) u16x
  function __builtin_align__ (line 150) | struct __device_builtin__ __builtin_align__(8) u32x
  function __builtin_align__ (line 162) | struct __device_builtin__ __builtin_align__(16) u64x
  function __device__ (line 228) | inline __device__ u32x operator ~  (const u32x a) { return u32x (~a.s0, ...
  function __device__ (line 284) | inline __device__ u64x operator ~  (const u64x a) { return u64x (~a.s0, ...
  function __builtin_align__ (line 290) | struct __device_builtin__ __builtin_align__(4) u8x
  function __device__ (line 400) | inline __device__ u32x operator ~  (const u32x a) { return u32x (~a.s0, ...
  function __device__ (line 456) | inline __device__ u64x operator ~  (const u64x a) { return u64x (~a.s0, ...
  function __builtin_align__ (line 462) | struct __device_builtin__ __builtin_align__(8) u8x
  function __device__ (line 588) | inline __device__ u32x operator ~  (const u32x a) { return u32x (~a.s0, ...
  function __device__ (line 644) | inline __device__ u64x operator ~  (const u64x a) { return u64x (~a.s0, ...
  function __builtin_align__ (line 650) | struct __device_builtin__ __builtin_align__(16) u8x
  function __device__ (line 808) | inline __device__ u32x operator ~  (const u32x a) { return u32x (~a.s0, ...
  function __device__ (line 864) | inline __device__ u64x operator ~  (const u64x a) { return u64x (~a.s0, ...
  type __device_builtin__ (line 868) | typedef __device_builtin__ struct
  type __device_builtin__ (line 869) | typedef __device_builtin__ struct
  type __device_builtin__ (line 870) | typedef __device_builtin__ struct
  type __device_builtin__ (line 871) | typedef __device_builtin__ struct
  type u8x (line 879) | typedef VTYPE(uchar,  VECT_SIZE) u8x;
  type u16x (line 880) | typedef VTYPE(ushort, VECT_SIZE) u16x;
  type u32x (line 881) | typedef VTYPE(uint,   VECT_SIZE) u32x;
  type u64x (line 882) | typedef VTYPE(ullong, VECT_SIZE) u64x;
  type vconv32_t (line 901) | typedef union vconv32
  type vconv64_t (line 923) | typedef union vconv64
  type siphash_constants_t (line 963) | typedef enum siphash_constants
  type bcrypt_constants_t (line 972) | typedef enum bcrypt_constants
  type md4_constants_t (line 983) | typedef enum md4_constants
  type md5_constants_t (line 1009) | typedef enum md5_constants
  type sha1_constants_t (line 1100) | typedef enum sha1_constants
  type sha2_32_constants_t (line 1115) | typedef enum sha2_32_constants
  type sha2_64_constants_t (line 1271) | typedef enum sha2_64_constants
  type ripemd160_constants_t (line 1377) | typedef enum ripemd160_constants
  type keccak_constants_t (line 1568) | typedef enum keccak_constants
  type mysql323_constants_t (line 1647) | typedef enum mysql323_constants
  type fortigate_constants_t (line 1654) | typedef enum fortigate_constants
  type blake2b_constants_t (line 1665) | typedef enum blake2b_constants
  type blake2s_constants_t (line 1678) | typedef enum blake2s_constants
  type sm3_constants_t (line 1691) | typedef enum sm3_constants
  type combinator_mode_t (line 1771) | typedef enum combinator_mode
  type digest_t (line 1779) | typedef struct digest
  type kernel_param_t (line 1786) | typedef struct kernel_param
  type salt_t (line 1806) | typedef struct salt
  type hcstat_table_t (line 1831) | typedef struct
  type cs_t (line 1838) | typedef struct
  type kernel_rule_t (line 1845) | typedef struct
  type pw_t (line 1851) | typedef struct pw
  type pw_idx_t (line 1859) | typedef struct pw_idx
  type bf_t (line 1867) | typedef struct bf
  type bs_word_t (line 1873) | typedef struct bs_word
  type plain_t (line 1879) | typedef struct plain
  type keyboard_layout_mapping_t (line 1891) | typedef struct keyboard_layout_mapping
  type hc_enc_t (line 1900) | typedef struct hc_enc

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AbstractPlaintextFileTest.java
  class AbstractPlaintextFileTest (line 40) | public class AbstractPlaintextFileTest {
    method readFile_emptyFile_processLineNeverCalled (line 46) | @Test
    method readFile_singleLine_processLineCalledOnceWithCorrectContent (line 60) | @Test
    method readFile_multipleLines_processLineCalledForEachLine (line 76) | @Test
    method readFile_processLineThrowsRuntimeException_errorAddedToReadStatistic (line 94) | @Test
    method readFile_processLineThrowsLmdbException_exceptionPropagated (line 110) | @Test(expected = LmdbException.class)
    method readFile_multipleExceptionLines_allErrorsAddedToReadStatistic (line 123) | @Test
    method interrupt_calledBeforeReadFile_readFileProcessesNoLines (line 140) | @Test
    method readFile_singleLineFile_fileProgressIsSetToNonZero (line 158) | @Test
    method readFile_fileWithContent_fileProgressReachesHundredPercent (line 173) | @Test
    method readFile_asciiContent_contentPreserved (line 190) | @Test
    class RecordingPlaintextFile (line 210) | private static class RecordingPlaintextFile extends AbstractPlaintextF...
      method RecordingPlaintextFile (line 214) | RecordingPlaintextFile(@NonNull File file, @NonNull ReadStatistic re...
      method processLine (line 218) | @Override
    class ThrowingPlaintextFile (line 228) | private static class ThrowingPlaintextFile extends AbstractPlaintextFi...
      method ThrowingPlaintextFile (line 232) | ThrowingPlaintextFile(@NonNull File file, @NonNull ReadStatistic rea...
      method processLine (line 237) | @Override

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AbstractProducerTest.java
  class AbstractProducerTest (line 46) | @RunWith(DataProviderRunner.class)
    method initProducer_configurationGiven_stateInitializedAndLogged (line 57) | @Test
    method releaseProducer_configurationGiven_stateInitializedAndLogged (line 70) | @Test
    method createSecretBase_secretGiven_bitsKilledAndLogged (line 83) | @Test
    method createSecretBase_secretGivenAndLogSecretBaseDisabledTraceEnabled_bitsKilledAndLogged (line 126) | @Test
    method createSecretBase_secretGivenAndLogSecretBaseEnabledTraceDisabled_bitsKilledAndLogged (line 159) | @Test
    method verifyReleaseProducer (line 193) | static void verifyReleaseProducer(AbstractProducer abstractProducer) {
    method verifyInitProducer (line 215) | static void verifyInitProducer(AbstractProducer abstractProducer) {
    method run_notInitialized_illegalStateExceptionThrown (line 239) | @Test(expected = IllegalStateException.class)
    method run_interruptedBeforeStarted_stateSetToNotRunning (line 252) | @Test
    method run_exceptionInProduceKeys_exceptionCaughtAndLoggedToError (line 278) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AbstractProducerTestImpl.java
  class AbstractProducerTestImpl (line 25) | public class AbstractProducerTestImpl extends AbstractProducer {
    method AbstractProducerTestImpl (line 27) | public AbstractProducerTestImpl(CProducer cProducer, Consumer consumer...
    method produceKeys (line 31) | @Override
    method processSecretBase (line 35) | @Override
    method processSecrets (line 39) | @Override

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AddressFileTest.java
  class AddressFileTest (line 40) | public class AddressFileTest {
    method processLine_validBitcoinAddress_addressConsumerCalledOnce (line 48) | @Test
    method processLine_validBitcoinAddress_readStatisticSuccessfulIncrements (line 64) | @Test
    method processLine_validSegwitAddress_addressConsumerCalledOnce (line 78) | @Test
    method processLine_emptyLine_unsupportedConsumerReceivesEmptyString (line 94) | @Test
    method processLine_emptyLine_readStatisticUnsupportedIncrements (line 110) | @Test
    method processLine_commentLine_unsupportedConsumerReceivesCommentString (line 124) | @Test
    method processLine_addressHeaderLine_unsupportedConsumerReceivesHeaderString (line 140) | @Test
    method processLine_calledTwiceWithValidAddresses_successfulCountIsTwo (line 156) | @Test
    method readFile_fileWithOneBitcoinAddress_addressConsumerCalledOnce (line 177) | @Test
    method readFile_emptyFile_consumersNeverCalled (line 195) | @Test
    method readFile_mixedValidAndCommentLines_correctCountsUpdated (line 210) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AddressFilesToLMDBTest.java
  class AddressFilesToLMDBTest (line 47) | @RunWith(DataProviderRunner.class)
    method init (line 50) | @Before
    method addressFilesToLMDB_addressFileDoesNotExists_throwsIllegalArgumentException (line 54) | @Test(expected = IllegalArgumentException.class)
    method addressFilesToLMDB_createLMDB_containingTestAddressesHashesWithCorrectAmount (line 68) | @Test
    method addressFilesToLMDB_createLMDBWithStaticAddresses_containingStaticHashes (line 94) | @Test
    method containsAddress_behavesCorrectly_withOrWithoutBloomFilter (line 112) | @Test
    method addressFilesToLMDB_addressWithAmountOfZero_noExceptionThrown (line 130) | @Test
    method containsAddress_returnsFalseForUnknownAddress (line 153) | @Test
    method interrupt_withNoCurrentFile_doesNotThrow (line 168) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AddressFormatNotAcceptedExceptionTest.java
  class AddressFormatNotAcceptedExceptionTest (line 32) | public class AddressFormatNotAcceptedExceptionTest {
    method constructor_withReason_messageContainsReason (line 35) | @Test
    method constructor_withReason_messageContainsExpectedPrefix (line 47) | @Test
    method constructor_withReason_messageEqualsExpected (line 59) | @Test
    method constructor_withReason_isInstanceOfException (line 71) | @Test
    method constructor_withReason_noCause (line 83) | @Test
    method getReason_withReason_returnsReason (line 97) | @Test
    method getReason_withEmptyReason_returnsEmptyString (line 110) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AddressToCoinTest.java
  class AddressToCoinTest (line 33) | public class AddressToCoinTest {
    method createAddressToCoin_publicKeyGiven_ToStringAndEqualsAndHashCode (line 38) | @Test
    method createAddressToCoin_invalidAddressSizeGiven_ToStringAndEqualsAndHashCode (line 58) | @Test(expected = IllegalArgumentException.class)

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AddressTxtLineTest.java
  class AddressTxtLineTest (line 41) | @RunWith(DataProviderRunner.class)
    method assertThatDefaultCoinIsSet (line 49) | private void assertThatDefaultCoinIsSet(AddressToCoin addressToCoin) {
    method fromLine_addressLineIsEmpty_throwsAddressFormatNotAcceptedException (line 54) | @Test
    method fromLine_addressLineStartsWithIgnoreLineSign_throwsAddressFormatNotAcceptedException (line 66) | @Test
    method fromLine_addressLineIsOnlyIgnoreLineSign_throwsAddressFormatNotAcceptedException (line 78) | @Test
    method fromLine_uncompressedBitcoinAddressGiven_returnHash160AndDefaultCoin (line 90) | @Test
    method fromLine_compressedBitcoinAddressGiven_returnHash160AndDefaultCoin (line 103) | @Test
    method fromLine_uncompressedBitcoinAddressGivenWithValidAmount_returnHash160AndSpecifiedCoin (line 116) | @Test
    method fromLine_uncompressedBitcoinAddressGivenWithInvalidAmount_returnHash160AndDefaultCoin (line 133) | @Test
    method fromLine_addressLineStartsWithAddressHeader_throwsAddressFormatNotAcceptedException (line 147) | @Test
    method fromLine_staticUnsupportedAddress_throwsAddressFormatNotAcceptedException (line 159) | @Test
    method fromLine_staticP2PKHAddress_returnPublicKeyHash (line 173) | @Test
    method fromLine_staticP2SHAddress_returnScriptHash (line 189) | @Test
    method fromLine_staticP2WPKHAddress_returnWitnessProgram (line 205) | @Test
    method fromLine_invalidP2WPKHAddressWithValidBase58Given_parseAnyway (line 221) | @Test
    method fromLine_invalidBech32WitnessVersion2_throwsAddressFormatNotAcceptedException (line 236) | @Test
    method fromLine_invalidP2WPKHAddressWithInvalidBase58Given_throwsAddressFormatNotAcceptedException (line 249) | @Test
    method fromLine_bitcoinCashAddressChecksumInvalid_parseAnyway (line 262) | @Test
    method fromLine_bitcoinCashAddressInternalPurpose_throwsAddressFormatNotAcceptedException (line 276) | @Test
    method fromLine_bitcoinAddressChecksumInvalid_parseAnyway (line 289) | @Test
    method fromLine_correctBase58_hash160equals (line 303) | @Test
    method parseBase58Address_correctBase58UseHigherSrcPos_copiedPartial (line 319) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AddressTypeTest.java
  class AddressTypeTest (line 30) | public class AddressTypeTest {
    method values_allConstants_countIsTwo (line 33) | @Test
    method values_p2pkhOrP2sh_nameIsExpected (line 42) | @Test
    method values_p2wpkh_nameIsExpected (line 51) | @Test
    method values_eachConstant_isNotNull (line 60) | @Test
    method valueOf_p2pkhOrP2sh_returnsExpectedConstant (line 70) | @Test
    method valueOf_p2wpkh_returnsExpectedConstant (line 79) | @Test
    method valueOf_unknownConstantName_throwsIllegalArgumentException (line 88) | @Test(expected = IllegalArgumentException.class)
    method ordinal_p2pkhOrP2sh_isZero (line 96) | @Test
    method ordinal_p2wpkh_isOne (line 105) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/AwaitTimeTests.java
  class AwaitTimeTests (line 23) | public class AwaitTimeTests {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/BIP39DataProvider.java
  class BIP39DataProvider (line 28) | public class BIP39DataProvider {
    method bip39TestVectors (line 38) | @DataProvider

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/BIP39KeyProducerTest.java
  class BIP39KeyProducerTest (line 43) | @RunWith(DataProviderRunner.class)
    method nextKey_givenKnownMnemonic_returnsExpectedPrivateKey (line 46) | @Test
    method nextBytes_calledTwice_returnsDeterministicByteArrays (line 65) | @Test
    method appendPath_givenBasePathAndIndex_returnsExtendedHDPath (line 89) | @Test
    method bip39Vector_givenEnglishMnemonic_returnsExpectedSeedAndXprv (line 106) | @Test
    method bip39Vector_givenTestVector_returnsExpectedSeedAndXprvForLanguage (line 129) | @Test
    method nextKey_counterOverflow_throwsException (line 163) | @Test(expected = NoMoreSecretsAvailableException.class)
    method testDefaultBip32PathConstant (line 186) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/BIP39WordlistTest.java
  class BIP39WordlistTest (line 31) | public class BIP39WordlistTest {
    method ideographicSpace_constant_hasCorrectUnicodeValue (line 34) | @Test
    method normalSpace_constant_hasCorrectValue (line 46) | @Test
    method ideographicSpace_constant_isOneCharacter (line 58) | @Test
    method normalSpace_constant_isOneCharacter (line 67) | @Test
    method getWordListStream_englishWordlist_returnsNonNullStream (line 78) | @Test
    method getWordListStream_chineseSimplifiedWordlist_returnsNonNullStream (line 87) | @Test
    method getWordListStream_chineseTraditionalWordlist_returnsNonNullStream (line 96) | @Test
    method getWordListStream_czechWordlist_returnsNonNullStream (line 105) | @Test
    method getWordListStream_frenchWordlist_returnsNonNullStream (line 114) | @Test
    method getWordListStream_italianWordlist_returnsNonNullStream (line 123) | @Test
    method getWordListStream_japaneseWordlist_returnsNonNullStream (line 132) | @Test
    method getWordListStream_koreanWordlist_returnsNonNullStream (line 141) | @Test
    method getWordListStream_portugueseWordlist_returnsNonNullStream (line 150) | @Test
    method getWordListStream_russianWordlist_returnsNonNullStream (line 159) | @Test
    method getWordListStream_spanishWordlist_returnsNonNullStream (line 168) | @Test
    method getWordListStream_turkishWordlist_returnsNonNullStream (line 177) | @Test
    method getWordListStream_allWordlists_returnNonNullStream (line 186) | @Test
    method fromLanguageName_lowercaseEnglish_returnsEnglishEnum (line 200) | @Test
    method fromLanguageName_lowercaseJapanese_returnsJapaneseEnum (line 212) | @Test
    method fromLanguageName_underscoredChineseSimplified_returnsChineseSimplifiedEnum (line 224) | @Test
    method fromLanguageName_uppercaseEnglish_returnsEnglishEnum (line 236) | @Test
    method fromLanguageName_mixedCaseFrench_returnsFrenchEnum (line 248) | @Test
    method fromLanguageName_hyphenatedChineseSimplified_returnsChineseSimplifiedEnum (line 260) | @Test
    method fromLanguageName_unknownLanguage_throwsException (line 273) | @Test(expected = IllegalArgumentException.class)
    method fromLanguageName_allWordlistNames_roundtripSucceeds (line 279) | @Test
    method getSeparator_japaneseWordlist_returnsIdeographicSpace (line 296) | @Test
    method getSeparator_englishWordlist_returnsNormalSpace (line 305) | @Test
    method getSeparator_chineseSimplifiedWordlist_returnsNormalSpace (line 314) | @Test
    method getSeparator_chineseTraditionalWordlist_returnsNormalSpace (line 323) | @Test
    method getSeparator_spanishWordlist_returnsNormalSpace (line 332) | @Test
    method getSeparator_allNonJapaneseWordlists_returnNormalSpace (line 341) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/Base36DecoderTest.java
  class Base36DecoderTest (line 29) | public class Base36DecoderTest {
    method decodeBase36ToFixedLengthBytes_validInput_exact20Bytes (line 34) | @Test
    method decodeBase36ToFixedLengthBytes_validInput_exact1Byte (line 48) | @Test
    method decodeBase36ToFixedLengthBytes_zeroBytes_producesAllZeros (line 62) | @Test
    method decodeBase36ToFixedLengthBytes_validInput_shorterThan20Bytes (line 78) | @Test
    method decodeBase36ToFixedLengthBytes_singleByteInput_leftPaddedWithZeros (line 98) | @Test
    method decodeBase36ToFixedLengthBytes_twoBytesInput_leftPaddedWithZeros (line 115) | @Test
    method decodeBase36ToFixedLengthBytes_validInput_longerThan20Bytes (line 135) | @Test
    method decodeBase36ToFixedLengthBytes_muchlongerInput_trimsToTargetLength (line 155) | @Test
    method decodeBase36ToFixedLengthBytes_maxByteValue_decodesCorrectly (line 175) | @Test
    method decodeBase36ToFixedLengthBytes_allMaxBytes_decodesCorrectly (line 189) | @Test
    method decodeBase36ToFixedLengthBytes_invalidCharacters_throwsException (line 205) | @Test(expected = NumberFormatException.class)
    method decodeBase36ToFixedLengthBytes_emptyString_throwsException (line 214) | @Test(expected = NumberFormatException.class)
    method decodeBase36ToFixedLengthBytes_invalidCharacterSpace_throwsException (line 223) | @Test(expected = NumberFormatException.class)
    method decodeBase36ToFixedLengthBytes_encodeDecodeRoundTrip_producesOriginalData (line 234) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/Bech32HelperTest.java
  class Bech32HelperTest (line 31) | public class Bech32HelperTest {
    method decodeBech32CharsetToValues_fullCharset_returnsValuesZeroToThirtyOne (line 36) | @Test
    method decodeBech32CharsetToValues_invalidCharacter_throwsException (line 49) | @Test(expected = IllegalArgumentException.class)
    method extractPKHFromBitcoinCashAddress_withoutPrefix_returnsCorrectHash160 (line 61) | @Test
    method extractPKHFromBitcoinCashAddress_withPrefix_returnsCorrectHash160 (line 75) | @Test
    method getWitnessPrograms_validBech32Data_returnsWitnessProgram (line 94) | @Test
    method getWitnessVersion_validBech32Data_returnsZero (line 110) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/BitHelperTest.java
  class BitHelperTest (line 31) | @RunWith(DataProviderRunner.class)
    method getKillBits_bitsGiven_killBitsEqualsExpectation (line 35) | @Test
    method convertBitsToSize_bitsGiven_sizeEqualsExpectation (line 47) | @Test
    method assertBatchSizeInBitsIsInRange_bitsGivenBelowMinimum_exceptionThrown (line 59) | @Test(expected = IllegalArgumentException.class)
    method assertBatchSizeInBitsCorrect_bitsGivenOverMaximum_exceptionThrown (line 68) | @Test(expected = IllegalArgumentException.class)
    method assertBatchSizeInBitsIsInRange_bitsGivenInRange_exceptionThrown (line 77) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ByteBufferUtilityTest.java
  class ByteBufferUtilityTest (line 38) | @RunWith(DataProviderRunner.class)
    method init (line 46) | @Before
    method freeByteBuffer_nullGiven_noExceptionThrown (line 52) | @Test
    method freeByteBuffer_cleanerIsNull_noExceptionThrown (line 65) | @Test
    method freeByteBuffer_freeAGivenByteBuffer_noExceptionThrown (line 88) | @Test
    method freeByteBuffer_freeAGivenByteBufferGivenTwice_noExceptionThrown (line 111) | @Test
    method createDummyByteBuffer (line 130) | private ByteBuffer createDummyByteBuffer(int size) {
    method createDummyByteArray (line 139) | private byte[] createDummyByteArray(int size) {
    method byteBufferToBytes_allBytesEquals (line 149) | @Test
    method byteBufferToBytes_idempotence (line 161) | @Test
    method byteArrayToByteBuffer_wrapped_allBytesEquals (line 176) | @Test
    method getHexFromByteBuffer_byteBufferProvided_returnHex (line 193) | @Test
    method getByteBufferFromHex_HexProvided_returnByteBuffer (line 210) | @Test
    method getAddressFromDirectBuffer (line 227) | private long getAddressFromDirectBuffer(DirectBuffer directBuffer) thr...
    method isDirectBufferFreed (line 238) | private boolean isDirectBufferFreed(DirectBuffer directBuffer) throws ...
    method ensureByteBufferCapacityFitsInt_zeroGiven_returnZero (line 262) | @Test
    method ensureByteBufferCapacityFitsInt_smallValueGiven_returnAsInt (line 274) | @Test
    method ensureByteBufferCapacityFitsInt_maxIntGiven_returnAsInt (line 286) | @Test
    method ensureByteBufferCapacityFitsInt_valueTooLarge_throwsException (line 298) | @Test(expected = IllegalArgumentException.class)
    method ensureByteBufferCapacityFitsInt_negativeValueGiven_throwsException (line 309) | @Test(expected = IllegalArgumentException.class)
    method allocateByteBufferDirectStrict_directAllocationEnabled_returnsDirectBuffer (line 325) | @Test
    method allocateByteBufferDirectStrict_directAllocationDisabled_throwsException (line 341) | @Test(expected = IllegalStateException.class)
    method bigIntegerToBytes_leadingZeroStripped (line 355) | @Test
    method bigIntegerToBytes_maxPrivateKeyGiven_returnWithoutLeadingZeros (line 370) | @Test
    method reverse_singleElement_noChange (line 394) | @Test
    method reverse_evenLengthArray_correctlyReversed (line 409) | @Test
    method reverse_oddLengthArray_correctlyReversed (line 423) | @Test
    method putToByteBuffer_arraySmallerThanBuffer_writtenCorrectly (line 439) | @Test
    method putToByteBuffer_arraySameSizeAsBuffer_writtenCompletely (line 451) | @Test
    method putToByteBuffer_arrayLargerThanBuffer_throwsBufferOverflowException (line 463) | @Test(expected = BufferOverflowException.class)

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ByteConversionTest.java
  class ByteConversionTest (line 31) | @RunWith(DataProviderRunner.class)
    method bytesToMib_bytesGiven_returnExpectedMib (line 37) | @Test
    method bytesToMib_zeroBytes_returnsZero (line 47) | @Test
    method bytesToMib_oneMib_returnsOne (line 56) | @Test
    method bytesToMib_twoMib_returnsTwo (line 68) | @Test
    method bytesToMib_largeValue_returnsCorrectMib (line 80) | @Test
    method bytesToMib_singleByte_returnsSmallFraction (line 92) | @Test
    method bytesToMib_maxLongValue_returnsLargeValue (line 102) | @Test
    method mibToBytes_mibGiven_returnExpectedBytes (line 113) | @Test
    method mibToBytes_zeroMib_returnsZeroBytes (line 123) | @Test
    method mibToBytes_oneMib_returnsOneMibInBytes (line 132) | @Test
    method mibToBytes_twoMib_returnsTwoMibInBytes (line 141) | @Test
    method mibToBytes_largeValue_returnsCorrectBytes (line 150) | @Test
    method mibToBytes_oneGigabyte_returnsCorrectBytes (line 162) | @Test
    method mibToBytes_bytesToMib_roundTrip_preservesValue (line 176) | @Test
    method bytesToMib_mibToBytes_roundTrip_preservesValue (line 189) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/CommonDataProvider.java
  class CommonDataProvider (line 32) | public class CommonDataProvider {
    method largeSecretsAsHex (line 53) | @DataProvider
    method cSecretFormat (line 71) | @DataProvider
    method endiannessScenarios (line 81) | @DataProvider
    type KeyProducerTypesLocal (line 91) | public enum KeyProducerTypesLocal {
    method keyProducerTypes (line 105) | @DataProvider
    method keyProducerTypeAndBitSize (line 117) | @DataProvider
    method mergeMany (line 132) | public static Object[][] mergeMany(Object[][]... providers) {
    method mergeRecursive (line 138) | private static void mergeRecursive(Object[][][] providers, int index, ...
    method bitsToSize (line 156) | @DataProvider
    method killBits (line 172) | @DataProvider
    method bytesToMib (line 188) | @DataProvider
    method mibToBytes (line 203) | @DataProvider
    method lmdbAmounts (line 217) | @DataProvider
    method lmdbIncreaseSize (line 265) | @DataProvider
    method bitSizesAtMostMax (line 279) | @DataProvider
    method compressedAndStaticAmount (line 296) | @DataProvider
    method staticAmount (line 311) | @DataProvider
    method compressed (line 324) | @DataProvider
    method addressSeperator (line 337) | @DataProvider
    method invalidP2WPKHAddressesValidBase58 (line 349) | @DataProvider
    method invalidBech32WitnessVersion2 (line 365) | @DataProvider
    method invalidBase58 (line 378) | @DataProvider
    method bitcoinAddressesCorrectBase58 (line 400) | @DataProvider
    method correctBase58 (line 415) | @DataProvider
    method srcPos (line 431) | @DataProvider
    method bitcoinCashAddressesChecksumInvalid (line 464) | @DataProvider
    method bitcoinCashAddressesInternalPurpose (line 487) | @DataProvider
    method createSecretBaseLogged (line 503) | @DataProvider
    method staticP2PKHAddresses (line 525) | @DataProvider
    method staticP2SHAddresses (line 535) | @DataProvider
    method staticP2WPKHAddresses (line 545) | @DataProvider
    method staticUnsupportedAddresses (line 555) | @DataProvider
    method transformFlatToObjectArrayArray (line 560) | private static Object[][] transformFlatToObjectArrayArray(Object[] obj...
    method allocateDirect (line 574) | @DataProvider
    method bloomFilterEnabled (line 590) | @DataProvider
    method largePrivateKeys (line 603) | @DataProvider
    method privateKeysTooLargeWithChunkSize (line 699) | @DataProvider
    method privateKeys32ByteRequiringStrip (line 712) | @DataProvider
    method bigIntegerVariants (line 728) | @DataProvider

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ConsumerJavaTest.java
  class ConsumerJavaTest (line 57) | @RunWith(DataProviderRunner.class)
    method createExamplePublicKeyBytesfromPrivateKey73 (line 72) | public static PublicKeyBytes[] createExamplePublicKeyBytesfromPrivateK...
    method initLMDB_lmdbNotExisting_noExceptionThrown (line 78) | @Test(expected = org.lmdbjava.LmdbNativeException.class)
    method toString_whenCalled_containsClassNameAndIdentityHash (line 90) | @ToStringTest
    method startStatisticsTimer_noExceptionThrown (line 106) | @Test
    method startStatisticsTimer_invalidparameter_throwsException (line 139) | @Test(expected = IllegalArgumentException.class)
    method interrupt_keysQueueNotEmpty_consumerNotRunningWaitedInternallyForTheDuration (line 148) | @AwaitTimeTest
    method interrupt_statisticsTimerStarted_executerServiceShutdown (line 196) | @Test
    method initLMDB_initialize_databaseOpened (line 230) | @Test
    method interrupt_consumerInitialized_databaseClosed (line 253) | @Test
    method runProber_testAddressGiven_hitExpected (line 277) | @Test
    method runProber_unknownAddressGiven_missExpectedAndLogMessagesInDebugAndTrace (line 335) | @Test
    method consumeKeys_invalidSecretGiven_continueExpectedAndNoExceptionThrown (line 397) | @Test
    method consumeKeys_withRuntimeKeyCalculationEnabled_logsError_whenPublicKeyHashIsInvalid (line 420) | @Test
    method consumeKeys_testVanityPattern_patternMatches (line 474) | @Test
    method interrupt_persistenceCloseThrowsException_runtimeExceptionThrown (line 567) | @Test(expected = RuntimeException.class)
    method createHash160ByteBuffer (line 590) | private ByteBuffer createHash160ByteBuffer() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/EndiannessConverterTest.java
  class EndiannessConverterTest (line 32) | @RunWith(DataProviderRunner.class)
    method mustConvertTest (line 38) | @Test
    method convertEndianTest (line 53) | @Test
    method getSourceOrder_returnsCorrectSourceOrder (line 73) | @Test
    method getTargetOrder_returnsCorrectTargetOrder (line 85) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/EqualHashCodeToStringTestHelper.java
  class EqualHashCodeToStringTestHelper (line 27) | public class EqualHashCodeToStringTestHelper {
    method EqualHashCodeToStringTestHelper (line 35) | public EqualHashCodeToStringTestHelper(Object instanceA, Object instan...
    method assertEqualsHashCodeToStringAIsDifferentToB (line 42) | public void assertEqualsHashCodeToStringAIsDifferentToB() {
    method assertEqualsHashCodeToStringAIsEqualToB (line 67) | public void assertEqualsHashCodeToStringAIsEqualToB() {
    method assertDifferenceReference (line 86) | private void assertDifferenceReference() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/FileHelperTest.java
  class FileHelperTest (line 37) | public class FileHelperTest {
    method stringsToFiles_emptyList_returnsEmptyList (line 45) | @Test
    method stringsToFiles_singlePath_returnsFileWithSamePath (line 54) | @Test
    method stringsToFiles_multiplePaths_returnsFilesInSameOrder (line 67) | @Test
    method assertFilesExists_emptyList_noExceptionThrown (line 84) | @Test
    method assertFilesExists_existingFile_noExceptionThrown (line 92) | @Test
    method assertFilesExists_multipleExistingFiles_noExceptionThrown (line 103) | @Test
    method assertFilesExists_missingFile_throwsIllegalArgumentException (line 115) | @Test(expected = IllegalArgumentException.class)
    method assertFilesExists_missingFile_exceptionMessageContainsFilePath (line 124) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/FinderTest.java
  class FinderTest (line 59) | @RunWith(DataProviderRunner.class)
    method interrupt_noProducersSet_noExceptionThrown (line 66) | @Test
    method interrupt_producersSetAndNotInitialized_noExceptionThrown (line 76) | @Test
    method interrupt_consumerStarted_consumerNotStopped (line 91) | @Test
    method shutdownAndAwaitTermination_noProducersSet_shutdownCalled (line 109) | @Test
    method shutdownAndAwaitTermination_producersSetAndNotInitialized_shutdownCalled (line 122) | @Test
    method shutdownAndAwaitTermination_producersSetAndInitialized_shutdownCalledAndAwaitTermination (line 138) | @AwaitTimeTest
    method getAllProducers_noProducersSet_returnEmptyList (line 178) | @Test
    method getAllProducers_producersSetAndNotInitialized_returnList (line 189) | @Test
    method startKeyProducer_keyProducerIdIsNull_ExceptionThrown (line 207) | @Test(expected = KeyProducerIdNullException.class)
    method startKeyProducer_keyProducerIdIsNotUnique_ExceptionThrown (line 219) | @Test(expected = KeyProducerIdIsNotUniqueException.class)
    method configureProducer_keyProducerIdIsUnknown_ExceptionThrown (line 235) | @Test(expected = KeyProducerIdUnknownException.class)
    method testFullCycle_keyProducerJavaSetAndInitialized_statesCorrect (line 258) | @Test
    method startKeyProducer_allConfiguredKeyProducerTypes_haveInstances (line 372) | @Test
    method configureProducerWithExamples (line 437) | private void configureProducerWithExamples(CFinder cFinder) {
    method configureKeyProducerJavaRandom (line 455) | private void configureKeyProducerJavaRandom(@Nullable String keyProduc...
    method configureKeyProducerJavaIncremental (line 463) | private void configureKeyProducerJavaIncremental(String keyProducerId,...
    method configureKeyProducerJavaBip39 (line 469) | private void configureKeyProducerJavaBip39(String keyProducerId, CFind...
    method configureKeyProducerJavaSocket (line 476) | private void configureKeyProducerJavaSocket(String keyProducerId, CFin...
    method configureKeyProducerJavaWebSocket (line 484) | private void configureKeyProducerJavaWebSocket(String keyProducerId, C...
    method configureKeyProducerJavaZmq (line 492) | private void configureKeyProducerJavaZmq(String keyProducerId, CFinder...
    method configureConsumerJava (line 500) | private void configureConsumerJava(CFinder cFinder) throws IOException {
    method assertProducerState (line 515) | private static void assertProducerState(List<Producer> producerStatePr...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/HexEncodeTest.java
  class HexEncodeTest (line 26) | public class HexEncodeTest {
    method encodeHexString_bouncyCastleAndApacheCommons_resultMustMatch (line 29) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/KeyUtilityTest.java
  class KeyUtilityTest (line 40) | @RunWith(DataProviderRunner.class)
    method createECKey_uncompressedKey_returnsCorrectPublicKeyHash (line 47) | @Test
    method createECKey_compressedKey_returnsCorrectPublicKeyHash (line 62) | @Test
    method getHash160ByteBufferFromBase58String_uncompressedPublicKeyAddress_returnsExpectedByteBuffer (line 79) | @Test
    method getHash160ByteBufferFromBase58String_compressedPublicKeyAddress_returnsExpectedByteBuffer (line 88) | @Test
    method byteBufferToAddress_isInverseOf_getHash160ByteBufferFromBase58String (line 97) | @Test
    method getHexFromByteBuffer_uncompressedPublicKeyHash_returnsExpectedHex (line 113) | @Test
    method getHexFromByteBuffer_compressedPublicKeyHash_returnsExpectedHex (line 122) | @Test
    method getByteBufferFromHex_uncompressedPublicKeyHashHex_returnsExpectedByteBuffer (line 133) | @Test
    method getByteBufferFromHex_compressedPublicKeyHashHex_returnsExpectedByteBuffer (line 142) | @Test
    method createSecret_maxBitLength_returnsNonEmptySecret (line 153) | @Test
    method createSecret_zeroBits_returnsZero (line 162) | @Test
    method createKeyDetails_uncompressedKey_returnsExpectedDetails (line 173) | @Test
    method createKeyDetails_compressedKey_returnsExpectedDetails (line 190) | @Test
    method killBits_valueWithAllBitsSetGiven_bitsKilled (line 209) | @Test
    method killBits_valueWithNotAllBitsSetGiven_bitsKilled (line 218) | @Test
    method ecKey_fromPrivate_randomValidInRange_succeeds (line 230) | @Test
    method ecKey_fromPrivate_minPrivateKey_throwsException (line 242) | @Test(expected = IllegalArgumentException.class)
    method ecKey_fromPrivate_maxPrivateKeyPlusOne_throwsException (line 248) | @Ignore("bitcoinj.ECKey.fromPrivate(...) accepts values > MAX_PRIVATE_...
    method ecKey_fromPrivate_minValidPrivateKey_noExceptionThrown (line 256) | @Test
    method ecKey_fromPrivate_maxPrivateKey_noExceptionThrown (line 265) | @Test
    method intToByteArray_zero_returnsFourZeroBytes (line 277) | @Test
    method intToByteArray_knownValue_returnsExpectedBigEndianBytes (line 289) | @Test
    method intToByteArray_minusOne_returnsAllFfBytes (line 301) | @Test
    method intToByteArray_intMaxValue_returnsExpectedBytes (line 313) | @Test
    method intToByteArray_intMinValue_returnsExpectedBytes (line 325) | @Test
    method intToByteArray_withOffset_writesExpectedBytesAtCorrectPosition (line 337) | @Test
    method byteArrayToInt_allZeroBytes_returnsZero (line 358) | @Test
    method byteArrayToInt_knownBytes_returnsExpectedInt (line 370) | @Test
    method byteArrayToInt_allFfBytes_returnsMinusOne (line 382) | @Test
    method byteArrayToInt_maxIntBytes_returnsMaxInt (line 394) | @Test
    method byteArrayToInt_withOffset_readsExpectedInt (line 406) | @Test
    method intToByteArray_byteArrayToInt_roundTrip_zero_preservesValue (line 421) | @Test
    method intToByteArray_byteArrayToInt_roundTrip_intMaxValue_preservesValue (line 434) | @Test
    method intToByteArray_byteArrayToInt_roundTrip_intMinValue_preservesValue (line 447) | @Test
    method intToByteArray_byteArrayToInt_roundTrip_minusOne_preservesValue (line 460) | @Test
    method intToByteArray_byteArrayToInt_roundTrip_knownValue_preservesValue (line 473) | @Test
    method byteArrayToIntArray_knownBytes_populatesIntAtOffset (line 488) | @Test
    method byteArrayToIntArray_withNonZeroIntArrayOffset_populatesCorrectSlot (line 502) | @Test
    method byteArrayToIntArray_withNonZeroByteArrayOffset_readsFromCorrectPosition (line 519) | @Test
    method createSecrets_returnStartSecretOnlyTrue_returnsOneSecret (line 537) | @Test
    method createSecrets_returnStartSecretOnlyFalse_returnsAllSecrets (line 555) | @Test
    method createSecrets_zeroLength_throwsException (line 573) | @Test(expected = NoMoreSecretsAvailableException.class)
    method bigIntegerToFixedLengthHex_knownBigInteger_correctHex (line 594) | @Test
    method bigIntegerFromUnsignedByteArray_exact32Bytes_constructsCorrectly (line 610) | @Test
    method bigIntegerFromUnsignedByteArray_wrongLength_throwsException (line 626) | @Test(expected = IllegalArgumentException.class)
    method toBase58_knownHash160_returnsExpectedBase58Address (line 638) | @Test
    method toBase58_compressedHash160_returnsExpectedBase58Address (line 652) | @Test
    method addressToByteBuffer_validAddress_returnsCorrectByteBuffer (line 668) | @Test
    method addressToByteBuffer_roundTripWithByteBufferToAddress_returnsOriginalAddress (line 682) | @Test
    method byteBufferToAddress_validBuffer_returnsCorrectAddress (line 699) | @Test
    method createMnemonics_validPrivateKeyBytes_returnsNonEmptyMnemonicString (line 714) | @Test
    method createMnemonics_validPrivateKeyBytes_containsAllWordLists (line 728) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/LMDBBase.java
  class LMDBBase (line 33) | public class LMDBBase {
    method createAndFillAndOpenLMDB (line 41) | protected Persistence createAndFillAndOpenLMDB(boolean useStaticAmount...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/LMDBPersistencePerformanceTest.java
  class LMDBPersistencePerformanceTest (line 45) | @RunWith(DataProviderRunner.class)
    method runProber_performanceTest (line 63) | @Test
    method createProducerThreads (line 114) | private void createProducerThreads(ThreadPoolExecutor threadPoolExecut...
    method createPublicKeyBytesArray (line 128) | private PublicKeyBytes[] createPublicKeyBytesArray() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/LMDBPersistenceTest.java
  class LMDBPersistenceTest (line 42) | @RunWith(DataProviderRunner.class)
    method putNewAmount_putNewAmount_correctAmountStored (line 67) | @Test
    method getDatabaseSize_initialLMDBSetTo1MiB_returnInitialDatabaseSize (line 98) | @Test
    method getDatabaseSize_valuesAdded_returnInitialDatabaseSize (line 117) | @Test
    method getDatabaseSize_initialLMDBSetTo1MiB_increaseDatabaseSize_returnResizedDatabaseSize (line 141) | @Test
    method getDatabaseSize_valuesAdded_increaseDatabaseSize_returnResizedDatabaseSize (line 162) | @Test
    method putNewAmount_initialLMDBSetTo1MiB_fillWithTooMuchValues_exceptionThrown (line 188) | @Test(expected = org.lmdbjava.Env.MapFullException.class)
    method putNewAmount_initialLMDBSetTo1MiB_fillWithTooMuchValues_increaseDatabaseSizeAndNoExceptionThrown (line 211) | @Test
    method fillWithRandomKeys (line 240) | private void fillWithRandomKeys(int keysToAdd, LMDBPersistence lmdbPer...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/LMDBPlatformAssume.java
  class LMDBPlatformAssume (line 29) | public class LMDBPlatformAssume implements PlatformAssume {
    method assumeLMDBExecution (line 31) | public void assumeLMDBExecution() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/LMDBToAddressFileTest.java
  class LMDBToAddressFileTest (line 41) | @RunWith(DataProviderRunner.class)
    method init (line 44) | @Before
    method writeAllAmountsToAddressFileAsDynamicWidthBase58BitcoinAddressWithAmount (line 48) | @Test
    method writeAllAmountsToAddressFileAsFixedWidthBase58BitcoinAddress (line 81) | @Test
    method writeAllAmountsToAddressFileAsHexHash (line 114) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/LogLevelChange.java
  class LogLevelChange (line 25) | public class LogLevelChange {
    method turnOff (line 26) | public void turnOff() {
    method setLevel (line 30) | public void setLevel(Level newLevel) {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/MainTest.java
  class MainTest (line 50) | public class MainTest {
    method interruptAfterDelay (line 77) | private void interruptAfterDelay(Main main, long delaySeconds) {
    method testRoundtrip_configurationsGiven_lmdbCreatedExportedAndRunFindSecretsFile (line 85) | @Test
    method testRoundtripOpenCLProducer_configurationsGiven_lmdbCreatedAndRunFindOpenCLDevice (line 95) | @Test
    method testOpenCLInfo_configurationGiven_noExceptionThrown (line 118) | @Test
    method main_noArgumentGiven_errorLogged (line 130) | @Test
    method printAllStackTracesWithDelay_includeDaemonsTrue_noExceptionThrown (line 149) | @Test
    method printAllStackTracesWithDelay_includeDaemonsFalse_noExceptionThrown (line 155) | @Test
    method fromJson_validJsonString_returnsExpectedConfiguration (line 163) | @Test
    method fromYaml_validYamlString_returnsExpectedConfiguration (line 177) | @Test
    method main_jsonExtensionPath_parsesAndRunsConfiguration (line 191) | @Test
    method main_jsExtensionPath_parsesAndRunsConfiguration (line 199) | @Test
    method main_yamlExtensionPath_parsesAndRunsConfiguration (line 207) | @Test
    method main_ymlExtensionPath_parsesAndRunsConfiguration (line 215) | @Test
    method main_unknownExtensionPath_throwsIllegalArgumentException (line 223) | @Test(expected = IllegalArgumentException.class)

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ManualDebugConstants.java
  class ManualDebugConstants (line 24) | public final class ManualDebugConstants {
    method ManualDebugConstants (line 26) | private ManualDebugConstants() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/MockConsumer.java
  class MockConsumer (line 24) | public class MockConsumer implements Consumer {
    method consumeKeys (line 28) | @Override
    method startConsumer (line 33) | @Override
    method interrupt (line 37) | @Override

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/MockKeyProducer.java
  class MockKeyProducer (line 28) | public class MockKeyProducer implements KeyProducer {
    method MockKeyProducer (line 35) | MockKeyProducer(KeyUtility keyUtility, Random random, int maximumBitLe...
    method MockKeyProducer (line 42) | MockKeyProducer(KeyUtility keyUtility, Random random) {
    method createSecrets (line 46) | @Override
    method interrupt (line 56) | @Override
    method getLogger (line 60) | @Override

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/MockKeyProducerTest.java
  class MockKeyProducerTest (line 34) | @RunWith(DataProviderRunner.class)
    method createSecrets_maximumBitLengthIs1BatchSizeIs0ReturnStartSecretOnlyIsTrue_returnMinPrivateKey (line 46) | @Test
    method createSecrets_maximumBitLengthIs1BatchSizeIs1ReturnStartSecretOnlyIsTrue_returnMinPrivateKey (line 62) | @Test
    method createSecrets_maximumBitLengthIs1BatchSizeIs2ReturnStartSecretOnlyIsTrue_returnMinPrivateKey (line 78) | @Test
    method createSecrets_maximumBitLengthIs1BatchSizeIs0ReturnStartSecretOnlyIsFalse_returnMinPrivateKey (line 96) | @Test
    method createSecrets_maximumBitLengthIs1BatchSizeIs1ReturnStartSecretOnlyIsFalse_returnMinPrivateKey (line 112) | @Test
    method createSecrets_maximumBitLengthIs1BatchSizeIs2ReturnStartSecretOnlyIsFalse_returnMinPrivateKey (line 129) | @Test
    method createSecrets_parameterBatchSizeInBitsFromDataProviderAndReturnStartSecretOnlyTrue_returnExpectedSecrets (line 150) | @Test
    method createSecrets_parameterBatchSizeInBitsFromDataProviderAndReturnStartSecretOnlyFalse_returnExpectedSecrets (line 165) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/NetworkParameterFactoryTest.java
  class NetworkParameterFactoryTest (line 31) | public class NetworkParameterFactoryTest {
    method getNetwork_noArguments_returnsNonNull (line 34) | @Test
    method getNetwork_calledTwice_returnsSameNetworkId (line 46) | @Test
    method getNetwork_differentFactoryInstances_returnSameNetworkId (line 59) | @Test
    method getNetwork_noArguments_returnsMainNet (line 73) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/OpenCLBuilderTest.java
  class OpenCLBuilderTest (line 32) | public class OpenCLBuilderTest {
    method build_openCLDeviceExisting_platformsAndDevicesReturned (line 35) | @Test
    method isOpenCL2_0OrGreater_OpenCLVersion1_2Given_ReturnFalse (line 55) | @Test
    method isOpenCL2_0OrGreater_OpenCLVersion3_0_CUDA_Given_ReturnFalse (line 61) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/OpenCLContextTest.java
  class OpenCLContextTest (line 29) | public class OpenCLContextTest {
    method constructor_defaultConstructor_noExceptionThrown (line 34) | @Test
    method constructor_mockLoggerGiven_noExceptionThrown (line 46) | @Test
    method init_defaultConfiguration_logsSelectedDeviceInfo (line 61) | @OpenCLTest

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/OpenCLDeviceTest.java
  class OpenCLDeviceTest (line 41) | public class OpenCLDeviceTest {
    method getByteOrder_endianLittleTrue_returnsLittleEndian (line 44) | @Test
    method getByteOrder_endianLittleFalse_returnsBigEndian (line 56) | @Test
    method toStringPretty_openCLDeviceExisting_stringCreated (line 70) | @Test
    method toStringPretty_staticDeviceData_stringCreated (line 90) | @Test
    method formatWorkItemSizes_emptyInput_returnsNone (line 187) | @Test
    method formatWorkItemSizes_singleElement_returnsElement (line 199) | @Test
    method formatWorkItemSizes_threeElements_returnsFormattedString (line 211) | @Test
    method formatWorkItemSizes_fiveElements_returnsFormattedString (line 223) | @Test
    method getComparableVersionFromDeviceVersion_openCLPrefix_removedCorrectly (line 238) | @Test
    method getComparableVersionFromDeviceVersion_cudaSuffix_removedCorrectly (line 250) | @Test
    method getComparableVersionFromDeviceVersion_noPrefixOrSuffix_versionUnchanged (line 262) | @Test
    method getComparableVersionFromDeviceVersion_emptyString_returnsEmptyVersion (line 274) | @Test
    method getComparableVersionFromDeviceVersion_trailingWhitespace_trimmedCorrectly (line 286) | @Test
    method createTestDeviceWithEndianness (line 304) | private static OpenCLDevice createTestDeviceWithEndianness(boolean end...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/OpenCLGridResultTest.java
  class OpenCLGridResultTest (line 32) | public class OpenCLGridResultTest {
    method getSecretKeyBase_validInput_returnsExpectedValue (line 35) | @Test
    method getSecretKeyBase_zeroBigInteger_returnsZero (line 50) | @Test
    method getWorkSize_validInput_returnsExpectedValue (line 67) | @Test
    method getWorkSize_workSizeOne_returnsOne (line 82) | @Test
    method getResult_validInput_returnsExpectedBuffer (line 99) | @Test
    method getResult_validInput_returnsSameBufferReference (line 115) | @Test
    method trimU32PrefixBytes_sevenByteArray_returnsFourBytes (line 132) | @Test
    method trimU32PrefixBytes_sevenByteArray_returnsLastFourBytes (line 144) | @Test
    method trimU32PrefixBytes_exactlyThreeBytes_returnsEmptyArray (line 159) | @Test
    method trimU32PrefixBytes_fourByteArray_returnsOneByteArray (line 171) | @Test
    method trimU32PrefixBytes_largeArray_returnsCorrectLength (line 184) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/OpenCLPlatformAssume.java
  class OpenCLPlatformAssume (line 28) | public class OpenCLPlatformAssume implements PlatformAssume {
    method assumeOpenCLLibraryLoadable (line 30) | public void assumeOpenCLLibraryLoadable() {
    method assumeOneOpenCL2_0OrGreaterDeviceAvailable (line 34) | public void assumeOneOpenCL2_0OrGreaterDeviceAvailable(List<OpenCLPlat...
    method assumeOpenCLLibraryLoadableAndOneOpenCL2_0OrGreaterDeviceAvailable (line 38) | public void assumeOpenCLLibraryLoadableAndOneOpenCL2_0OrGreaterDeviceA...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/OpenCLPlatformSelectorTest.java
  class OpenCLPlatformSelectorTest (line 36) | public class OpenCLPlatformSelectorTest {
    method select_validPlatformAndDeviceIndex_returnsExpectedSelection (line 45) | @Test
    method select_deviceTypeFilter_onlyMatchingDeviceSelected (line 61) | @Test
    method select_secondPlatformSelected_returnsDeviceFromSecondPlatform (line 76) | @Test
    method select_negativePlatformIndex_throwsIllegalArgumentException (line 93) | @Test(expected = IllegalArgumentException.class)
    method select_platformIndexTooLarge_throwsIllegalArgumentException (line 103) | @Test(expected = IllegalArgumentException.class)
    method select_emptyPlatformList_throwsIllegalArgumentException (line 113) | @Test(expected = IllegalArgumentException.class)
    method select_negativeDeviceIndex_throwsIllegalArgumentException (line 122) | @Test(expected = IllegalArgumentException.class)
    method select_deviceIndexTooLarge_throwsIllegalArgumentException (line 133) | @Test(expected = IllegalArgumentException.class)
    method select_noDeviceMatchingType_throwsIllegalArgumentException (line 144) | @Test(expected = IllegalArgumentException.class)
    method createTestPlatform (line 157) | private static OpenCLPlatform createTestPlatform(String name, OpenCLDe...
    method createTestDevice (line 161) | private static OpenCLDevice createTestDevice(long deviceType) {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/OpenCLPlatformTest.java
  class OpenCLPlatformTest (line 36) | public class OpenCLPlatformTest {
    method constructor_validArguments_returnsPlatform (line 39) | @Test
    method toString_containsPlatformName (line 56) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/PlatformAssume.java
  type PlatformAssume (line 31) | public interface PlatformAssume {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/PrivateKeyTooLargeExceptionTest.java
  class PrivateKeyTooLargeExceptionTest (line 33) | public class PrivateKeyTooLargeExceptionTest {
    method constructor_validArguments_messageContainsProvidedKey (line 40) | @Test
    method constructor_validArguments_messageContainsMaxAllowedKey (line 49) | @Test
    method constructor_validArguments_messageContainsBatchSizeInBits (line 58) | @Test
    method constructor_validArguments_messageContainsReference (line 67) | @Test
    method constructor_validArguments_isInstanceOfIllegalArgumentException (line 76) | @Test
    method constructor_validArguments_noCause (line 85) | @Test
    method getProvidedKey_validArguments_returnsProvidedKey (line 96) | @Test
    method getMaxAllowedKey_validArguments_returnsMaxAllowedKey (line 110) | @Test
    method getBatchSizeInBits_validArguments_returnsBatchSizeInBits (line 124) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/PrivateKeyValidatorTest.java
  class PrivateKeyValidatorTest (line 29) | @RunWith(DataProviderRunner.class)
    method getMaxPrivateKeyForBatchSize_batchSize0_returnsMaxPrivateKey (line 35) | @Test
    method getMaxPrivateKeyForBatchSize_batchSize1_returnsMaxMinus1 (line 47) | @Test
    method getMaxPrivateKeyForBatchSize_maxAllowedBitSize_returnsMinimumSafeKey (line 59) | @Test
    method getMaxPrivateKeyForBatchSize_bitSizeNegative_throwsException (line 73) | @Test(expected = IllegalArgumentException.class)
    method getMaxPrivateKeyForBatchSize_bitSizeTooLarge_throwsException (line 79) | @Test(expected = IllegalArgumentException.class)
    method getMaxPrivateKeyForBatchSize_tooLarge_throwsException (line 85) | @Test(expected = IllegalStateException.class)
    method isInvalidWithBatchSize_keyTooLarge_returnsTrue (line 96) | @Test
    method isInvalidWithBatchSize_keyWithinLimit_returnsFalse (line 109) | @Test
    method isOutsidePrivateKeyRange_minPrivateKey_returnsTrue (line 125) | @Test
    method isOutsidePrivateKeyRange_minValidPrivateKey_returnsFalse (line 134) | @Test
    method isOutsidePrivateKeyRange_maxPrivateKey_returnsFalse (line 143) | @Test
    method isOutsidePrivateKeyRange_zero_returnsTrue (line 152) | @Test
    method isOutsidePrivateKeyRange_belowMin_returnsTrue (line 161) | @Test
    method isOutsidePrivateKeyRange_aboveMax_returnsTrue (line 173) | @Test
    method returnValidPrivateKey_validKey_returnsSameKey (line 187) | @Test
    method returnValidPrivateKey_tooSmall_returnsReplacement (line 199) | @Test
    method returnValidPrivateKey_tooLarge_returnsReplacement (line 211) | @Test
    method replaceInvalidPrivateKeys_mixedArray_replacesInvalids (line 225) | @Test
    method replaceInvalidPrivateKeys_allValidKeys_keepsOriginalValues (line 243) | @Test
    method replaceInvalidPrivateKeys_allInvalidKeys_replacesAll (line 260) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ProbeAddressesOpenCLTest.java
  class ProbeAddressesOpenCLTest (line 60) | @RunWith(DataProviderRunner.class)
    method init (line 83) | @Before
    method fillAddressesFiles (line 88) | public void fillAddressesFiles(File file) throws IOException {
    method createTemporaryAddressesFile (line 92) | public void createTemporaryAddressesFile() throws IOException {
    method joclTest (line 97) | @Test
    method reverseEngineering_startPoints (line 244) | @Test
    method calcAddrsFixZeroCl_loadWithoutErrors (line 281) | @Test
    method createKeys_bitsLowerThan25_use32BitNevertheless (line 401) | @Test
    method createKeys_bitsLowerThanGridSize_useMoreNevertheless (line 422) | @Test
    method dataProvider_largePrivateKeys_containsAtLeastOneEncodingWithLeadingZeroByte (line 446) | @Test
    method dataProvider_largePrivateKeys_allHaveLeadingZeroEncoding (line 463) | @Test
    method setSrcPrivateKeyChunk_privateKeyTooLarge_throwsException (line 476) | @OpenCLTest
    method setSrcPrivateKeyChunk_handlesLeadingZero_correctlySerializesTo32Bytes (line 493) | @Test
    method createKeys_fromLargePrivateKey_generatesValidPublicKeys (line 538) | @Test
    method createKeys_fromRandomPrivateKey_correctlyHashesAndVerifiesResults (line 569) | @Test
    method assertAllRuntimePublicKeyCalculationsValid (line 601) | private static void assertAllRuntimePublicKeyCalculationsValid(PublicK...
    method assertRuntimePublicKeyCalculationValid (line 607) | private static void assertRuntimePublicKeyCalculationValid(PublicKeyBy...
    method assertPublicKeyBytesCalculatedCorrect (line 612) | private static void assertPublicKeyBytesCalculatedCorrect(PublicKeyByt...
    method hashPublicKeysFast (line 681) | private static void hashPublicKeysFast(PublicKeyBytes[] publicKeys, fi...
    method hashPublicKeys (line 698) | private static void hashPublicKeys(PublicKeyBytes[] publicKeys, final ...
    method getPublicKeyFromByteBuffer (line 718) | @Deprecated
    method dumpIntArray (line 742) | @Deprecated
    method windowNaf (line 752) | @Deprecated

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ProducerJavaSecretsFilesTest.java
  class ProducerJavaSecretsFilesTest (line 51) | @RunWith(DataProviderRunner.class)
    type PrivateKey (line 61) | enum PrivateKey {
      method PrivateKey (line 71) | PrivateKey(String string) {
      method getSHA256 (line 75) | public String getSHA256() {
      method getBigInteger (line 80) | public BigInteger getBigInteger() {
      method getPublicKeyBytes (line 84) | public PublicKeyBytes getPublicKeyBytes() {
      method getWiF (line 88) | public String getWiF() {
      method getHex (line 92) | public String getHex() {
    method initProducer_configurationGiven_stateInitializedAndLogged (line 98) | @Test
    method releaseProducer_configurationGiven_stateInitializedAndLogged (line 111) | @Test
    method produceKeys_noFileConfigured_noKeysCreated (line 124) | @Test
    method produceKeys_filesConfigured_keysCreated (line 140) | @Test
    method createSecretsFiles (line 177) | private List<File> createSecretsFiles(CSecretFormat secretFormat) thro...
    method fillSecretsFile (line 204) | private void fillSecretsFile(File file, Iterable<PrivateKey> secrets, ...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ProducerJavaTest.java
  class ProducerJavaTest (line 37) | @RunWith(DataProviderRunner.class)
    method initProducer_configurationGiven_stateInitializedAndLogged (line 48) | @Test
    method toString_whenCalled_containsClassNameAndIdentityHash (line 61) | @ToStringTest
    method releaseProducer_configurationGiven_stateInitializedAndLogged (line 78) | @Test
    method produceKeys_BatchSizeInBitsEqualsKeyMaxNumBits_noExceptionThrown (line 91) | @Test
    method produceKeys_KeyMaxNumBitsLowerThanBatchSizeInBits_produceBatchSizeInBitsNevertheless (line 115) | @Test
    method produceKeys_privateKeyMaxNumBitsIsVeryLowAndProduceReplacedKeys_keysEqualsReplacement (line 151) | @Test
    method produceKeys_privateKeyMaxNumBitsIsLowAndProduceReplacedKeys_keysEqualsReplacement (line 173) | @Test
    method produceKeys_SomeBitRanges_consumerContainsData (line 209) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ProducerOpenCLTest.java
  class ProducerOpenCLTest (line 37) | public class ProducerOpenCLTest {
    method initProducer_configurationGiven_stateInitializedAndLogged (line 48) | @OpenCLTest
    method releaseProducer_configurationGiven_stateInitializedAndLoggedAndExecuterServiceShutdown (line 63) | @OpenCLTest
    method initProducer_configurationGiven_stateInitializedAndOpenCLContextSet (line 79) | @OpenCLTest
    method releaseProducers_notInitialized_noExceptionThrown (line 103) | @Test
    method releaseProducers_initialized_noExceptionThrownAndOpenCLContextFreed (line 116) | @Test
    method getFreeThreads_notInitialized_numberOfFreeThreadsReturned (line 141) | @Test
    method getFreeThreads_initialized_numberOfFreeThreadsReturned (line 157) | @Test
    method waitTillFreeThreadsInPool_notInitialized_returnImmediately (line 179) | @Test
    method waitTillFreeThreadsInPool_initialized_returnImmediately (line 194) | @Test
    method waitTillFreeThreadsInPool_initializedAndThreadPoolFull_doNotReturn (line 213) | @Test
    method produceKeys_notInitialized_illegalStateExceptionThrown (line 250) | @Test(expected = IllegalStateException.class)
    method produceKeys_initialized_keysInConsumer (line 265) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ProducerStateTest.java
  class ProducerStateTest (line 26) | public class ProducerStateTest {
    method values_allStatesPresent_countIsFour (line 29) | @Test
    method values_ordinalOfUninitialized_isZero (line 38) | @Test
    method values_ordinalOfInitialized_isOne (line 44) | @Test
    method values_ordinalOfRunning_isTwo (line 50) | @Test
    method values_ordinalOfNotRunning_isThree (line 56) | @Test
    method name_uninitialized_returnsExpectedString (line 64) | @Test
    method name_initialized_returnsExpectedString (line 70) | @Test
    method name_running_returnsExpectedString (line 76) | @Test
    method name_notRunning_returnsExpectedString (line 82) | @Test
    method valueOf_uninitializedString_returnsUninitializedState (line 90) | @Test
    method valueOf_initializedString_returnsInitializedState (line 96) | @Test
    method valueOf_runningString_returnsRunningState (line 102) | @Test
    method valueOf_notRunningString_returnsNotRunningState (line 108) | @Test
    method valueOf_unknownString_throwsIllegalArgumentException (line 114) | @Test(expected = IllegalArgumentException.class)

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/PublicKeyBytesTest.java
  class PublicKeyBytesTest (line 45) | public class PublicKeyBytesTest {
    method publicKeyBytes_fromPublicKey_matchesExpectedHashes (line 51) | @Test
    method publicKeyBytes_toStringEqualsAndHashCode_consistent (line 77) | @Test
    method maxPrivateKeyAsHexString_isEqualToConstant (line 98) | @Test
    method runtimePublicKeyCalculationCheck_validKey_returnsTrue (line 109) | @Test
    method runtimePublicKeyCalculationCheck_invalidCompressedHash_returnsFalse (line 127) | @Test
    method runtimePublicKeyCalculationCheck_invalidUncompressedHash_returnsFalse (line 148) | @Test
    method runtimePublicKeyCalculationCheck_invalidCompressedAndUncompressed_returnsFalse (line 169) | @Test
    method assembleUncompressedPublicKey_validXY_correctlyAssembles (line 191) | @Test
    method assembleUncompressedPublicKey_allZeros_createsValidKey (line 212) | @Test
    method assembleUncompressedPublicKey_validXAndY_assemblesCorrectly (line 228) | @Test
    method toString_whenCalled_containsClassNameAndPrivateKey (line 248) | @ToStringTest
    method fromPrivate_validSecretKey_returnsPublicKeyBytesWithCorrectKey (line 264) | @Test
    method fromPrivate_validSecretKey_returnsMatchingUncompressedPubKey (line 276) | @Test
    method fromPrivate_validSecretKey_returnsMatchingCompressedPubKey (line 289) | @Test
    method fromPrivate_minValidPrivateKey_noExceptionThrown (line 302) | @Test
    method getSecretKey_constructedWithKnownKey_returnsCorrectKey (line 316) | @Test
    method getCompressed_constructedFromUncompressed_returnsValidCompressedKey (line 332) | @Test
    method getUncompressed_constructedWithUncompressed_returnsSameArray (line 349) | @Test
    method isOutsidePrivateKeyRange_validKey_returnsFalse (line 366) | @Test
    method isOutsidePrivateKeyRange_keyAboveMax_returnsTrue (line 380) | @Test
    method isOutsidePrivateKeyRange_keyBelowMin_returnsTrue (line 394) | @Test
    method sha256hash160Fast_knownInput_matchesCryptoUtilsResult (line 410) | @Test
    method sha256hash160Fast_compressedKey_matchesCryptoUtilsResult (line 425) | @Test
    method sha256hash160Fast_resultLength_isRipemd160HashLength (line 440) | @Test
    method createCompressedBytes_evenYCoordinate_prefixIs02 (line 454) | @Test
    method createCompressedBytes_knownKey_matchesECKeyCompressed (line 475) | @Test
    method createCompressedBytes_resultLength_isCompressedKeyLength (line 489) | @Test
    method createCompressedBytes_xCoordinate_matchesUncompressedXCoordinate (line 502) | @Test
    method constructor_fourArgs_setsAllFields (line 520) | @Test
    method isAllCoordinateBytesZero_validKey_returnsFalse (line 540) | @Test
    method isAllCoordinateBytesZero_allCoordinateBytesZero_returnsTrue (line 554) | @Test
    method isAllCoordinateBytesZero_validKeyOnlyLastByteNonZero_returnsFalse (line 567) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/RandomSecretSupplierTest.java
  class RandomSecretSupplierTest (line 31) | public class RandomSecretSupplierTest {
    method nextSecret_zeroBitLength_returnsZero (line 34) | @Test
    method nextSecret_256BitLength_returnsNonNullValue (line 46) | @Test
    method nextSecret_256BitLength_returnValueFitsIn256Bits (line 58) | @Test
    method nextSecret_1BitLength_returnsZeroOrOne (line 72) | @Test
    method nextSecret_seededRandom_returnsDeterministicValue (line 86) | @Test
    method nextSecret_consecutiveCalls_canProduceDifferentValues (line 103) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/ReadStatisticTest.java
  class ReadStatisticTest (line 33) | public class ReadStatisticTest {
    method readStatistic_newInstance_successfulIsZero (line 36) | @Test
    method readStatistic_newInstance_unsupportedReasonsIsEmpty (line 45) | @Test
    method readStatistic_newInstance_unsupportedTotalIsZero (line 54) | @Test
    method readStatistic_newInstance_currentFileProgressIsZero (line 63) | @Test
    method readStatistic_newInstance_errorsIsEmpty (line 72) | @Test
    method readStatistic_incrementUnsupported_addsReasonToMap (line 83) | @Test
    method readStatistic_incrementUnsupportedTwiceWithSameReason_accumulatesCount (line 95) | @Test
    method readStatistic_incrementUnsupportedWithDifferentReasons_eachReasonTrackedSeparately (line 108) | @Test
    method readStatistic_getUnsupportedTotal_sumsAllReasons (line 125) | @Test
    method readStatistic_setSuccessful_reflectsNewValue (line 142) | @Test
    method readStatistic_setCurrentFileProgress_reflectsNewValue (line 154) | @Test
    method readStatistic_addError_errorsPresentInList (line 166) | @Test
    method toString_defaultInstance_containsAllFieldNames (line 181) | @Test
    method toString_withModifiedValues_containsUpdatedValues (line 198) | @Test
    method toString_withModifiedValues_equalsExpectedFullString (line 216) | @Test
    method createReadStatisticWithAllFieldsSet (line 229) | private static ReadStatistic createReadStatisticWithAllFieldsSet() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/SecretsFileTest.java
  class SecretsFileTest (line 42) | public class SecretsFileTest {
    method processLine_bigIntegerFormat_consumerReceivesExpectedSecret (line 51) | @Test
    method processLine_sha256Format_consumerReceivesExpectedSecret (line 67) | @Test
    method processLine_sha256Format_singleByteValue_consumerReceivesExpected (line 83) | @Test
    method processLine_stringDoSha256Format_consumerReceivesHashOfInput (line 99) | @Test
    method processLine_dumpedPrivateKeyFormat_consumerReceivesNonNullPositiveSecret (line 117) | @Test
    method processLine_dumpedPrivateKeyFormat_consumerReceivesExpectedPrivateKey (line 134) | @Test
    method processLine_bigIntegerFormat_calledTwice_consumerCalledTwice (line 149) | @Test
    method readFile_fileWithTwoLines_consumerCalledTwice (line 169) | @Test
    method readFile_emptyFile_consumerNeverCalled (line 187) | @Test
    method interrupt_calledBeforeReadFile_noLinesProcessed (line 204) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/SeparatorFormatTest.java
  class SeparatorFormatTest (line 35) | @RunWith(DataProviderRunner.class)
    method split_separatorBetweenTwoParts_returnsSplitParts (line 42) | @Test
    method split_inputEqualsSeparator_returnsEmptyStrings (line 63) | @Test
    method split_noSeparatorInInput_returnsWholeInput (line 82) | @Test
    method split_inputWithMultipleValidSeparators_recursivelySplitsAll (line 99) | @Test
    method split_multipleSeparatorsPresent_recursivelySplitsAll (line 118) | @Test
    method split_inputStartsAndEndsWithSeparator_returnsEmptyAndMiddleAndEmpty (line 137) | @Test
    method getSortedSeparators_doubleColonBeforeColon (line 157) | @Test
    method split_trailingSeparator_returnsEmptyLastPart (line 173) | @Test
    method split_leadingSeparator_returnsEmptyFirstPart (line 192) | @Test
    method getSymbol_eachSeparator_returnsExpectedString (line 211) | @Test
    method allSeparators_areUnique (line 219) | @Test
    method split_spaceSeparator_surroundedByText_returnsParts (line 228) | @Test
    method split_recursiveSplitting_allRelevantSeparatorsAreResolvedInOrder (line 235) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/StatisticsTest.java
  class StatisticsTest (line 26) | public class StatisticsTest {
    method createStatisticsMessage_statisticsGiven_returnExpectedStatisticsMessage (line 29) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaIncrementalTest.java
  class CKeyProducerJavaIncrementalTest (line 29) | public class CKeyProducerJavaIncrementalTest {
    method getStartAddress_defaultStartAddress_returnsMinValidPrivateKey (line 35) | @Test
    method getStartAddress_customUppercaseHexStartAddress_returnsExpectedBigInteger (line 47) | @Test
    method getStartAddress_customLowercaseHexStartAddress_returnsExpectedBigInteger (line 60) | @Test
    method getStartAddress_maxPrivateKeyHexStartAddress_returnsMaxPrivateKey (line 73) | @Test
    method getEndAddress_defaultEndAddress_returnsMaxPrivateKey (line 88) | @Test
    method getEndAddress_customUppercaseHexEndAddress_returnsExpectedBigInteger (line 100) | @Test
    method getEndAddress_customLowercaseHexEndAddress_returnsExpectedBigInteger (line 113) | @Test
    method getEndAddress_maxPrivateKeyHexEndAddress_returnsMaxPrivateKey (line 126) | @Test
    method getEndAddress_minValidPrivateKeyHexEndAddress_returnsMinValidPrivateKey (line 139) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/configuration/CProducerTest.java
  class CProducerTest (line 26) | public class CProducerTest {
    method init (line 30) | @Before
    method batchSizeInBits_configurationConstantsSet_isValidDefaultValue (line 35) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/configuration/UnknownSecretFormatExceptionTest.java
  class UnknownSecretFormatExceptionTest (line 32) | public class UnknownSecretFormatExceptionTest {
    method constructor_withBigInteger_messageContainsFormatName (line 35) | @Test
    method constructor_withSha256_messageContainsFormatName (line 47) | @Test
    method constructor_withStringDoSha256_messageContainsFormatName (line 59) | @Test
    method constructor_withDumpedPrivateKey_messageContainsFormatName (line 71) | @Test
    method constructor_withBigInteger_messageContainsExpectedPrefix (line 83) | @Test
    method constructor_withBigInteger_messageEqualsExpected (line 95) | @Test
    method constructor_withSha256_messageEqualsExpected (line 107) | @Test
    method constructor_withBigInteger_isInstanceOfIllegalArgumentException (line 119) | @Test
    method constructor_withBigInteger_noCause (line 131) | @Test
    method getSecretFormat_withBigInteger_returnsSecretFormat (line 145) | @Test
    method getSecretFormat_withSha256_returnsSecretFormat (line 158) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/eckey/Secp256k1Test.java
  class Secp256k1Test (line 18) | public class Secp256k1Test {
    method testme (line 20) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/AbstractKeyProducerQueueBufferedTest.java
  class AbstractKeyProducerQueueBufferedTest (line 44) | public class AbstractKeyProducerQueueBufferedTest {
    method setUp (line 51) | @Before
    class TestKeyProducer (line 56) | static class TestKeyProducer extends AbstractKeyProducerQueueBuffered<...
      method TestKeyProducer (line 57) | public TestKeyProducer(CKeyProducerJavaReceiver config, KeyUtility k...
      method TestKeyProducer (line 60) | public TestKeyProducer(CKeyProducerJavaReceiver config, KeyUtility k...
      method getReadTimeout (line 64) | @Override
      method interrupt (line 69) | @Override
    method createTestKeyProducer (line 75) | private TestKeyProducer createTestKeyProducer(CKeyProducerJavaReceiver...
    method createSecrets_returnsSecret_whenAvailableInQueue (line 79) | @Test
    method createSecrets_readsMultipleSecrets (line 94) | @Test
    method createSecrets_throwsException_onInvalidLength (line 113) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_throwsException_onTimeout (line 124) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_throwsException_whenShouldStopSet (line 133) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_logsSecret_whenEnabled (line 142) | @Test
    method addSecret_throwsWhenQueueFull (line 161) | @Test()

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/ConnectionUtilsTest.java
  class ConnectionUtilsTest (line 31) | public class ConnectionUtilsTest {
    method setup (line 35) | @Before
    method teardown (line 40) | @After
    method findFreePort (line 45) | private int findFreePort() {
    method waitUntilTcpPortOpen_whenServerAlreadyListening_returnsImmediately (line 53) | @Test
    method waitUntilTcpPortOpen_whenServerStartsLate_returnsAfterStart (line 67) | @Test
    method waitUntilTcpPortOpen_whenPortNeverOpens_throwsException (line 89) | @Test(expected = IllegalStateException.class)

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerIdIsNotUniqueExceptionTest.java
  class KeyProducerIdIsNotUniqueExceptionTest (line 32) | public class KeyProducerIdIsNotUniqueExceptionTest {
    method constructor_withId_messageContainsId (line 35) | @Test
    method constructor_withId_messageContainsExpectedPrefix (line 47) | @Test
    method constructor_withId_messageEqualsExpected (line 59) | @Test
    method constructor_withId_isInstanceOfRuntimeException (line 71) | @Test
    method constructor_withId_noCause (line 83) | @Test
    method getId_withId_returnsId (line 97) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerIdNullExceptionTest.java
  class KeyProducerIdNullExceptionTest (line 32) | public class KeyProducerIdNullExceptionTest {
    method constructor_noArg_messageContainsNull (line 35) | @Test
    method constructor_noArg_messageEqualsExpected (line 44) | @Test
    method constructor_noArg_isInstanceOfRuntimeException (line 53) | @Test
    method constructor_noArg_noCause (line 62) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerIdUnknownExceptionTest.java
  class KeyProducerIdUnknownExceptionTest (line 32) | public class KeyProducerIdUnknownExceptionTest {
    method constructor_withId_messageContainsId (line 35) | @Test
    method constructor_withId_messageContainsExpectedPrefix (line 47) | @Test
    method constructor_withId_messageEqualsExpected (line 59) | @Test
    method constructor_withId_isInstanceOfRuntimeException (line 71) | @Test
    method constructor_withId_noCause (line 83) | @Test
    method constructor_withNullId_messageContainsNull (line 95) | @Test
    method getId_withId_returnsId (line 106) | @Test
    method getId_withNullId_returnsNull (line 119) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaBip39Test.java
  class KeyProducerJavaBip39Test (line 37) | public class KeyProducerJavaBip39Test {
    method setUp (line 46) | @Before
    method createKeyProducerJavaBip39 (line 51) | private KeyProducerJavaBip39 createKeyProducerJavaBip39(CKeyProducerJa...
    method generateSecrets (line 55) | private BigInteger[] generateSecrets() throws NoMoreSecretsAvailableEx...
    method testBip39 (line 68) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaIncrementalTest.java
  class KeyProducerJavaIncrementalTest (line 138) | public class KeyProducerJavaIncrementalTest {
    method setUp (line 150) | @Before
    method createKeyProducerJavaIncremental (line 159) | private KeyProducerJavaIncremental createKeyProducerJavaIncremental(St...
    method createSecrets_returnStartSecretOnlyTrue_returnsOneSecret (line 170) | @Test
    method createSecrets_returnStartSecretOnlyFalse_returnsBatchSecrets (line 182) | @Test
    method createSecrets_startExceedsEnd_throwsException (line 201) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_batchExceedsEnd_throwsException (line 214) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_currentValueAdvancesByBatchSize (line 227) | @Test
    method verifySecrets (line 242) | private void verifySecrets(BigInteger[] secrets, BigInteger expectedSt...
    method createSecrets_endAddressExactlyAtBatchBoundary_allBatchesValid (line 252) | @Test
    method createSecrets_threeBatches_twoElementsEach_thirdThrowsException (line 278) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_endAddressInclusive_butPartialBatchNotAllowed_throwsException (line 299) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_endAddressInclusive_partialBatchAllowedWithReturnStartOnly_noException (line 319) | @Test
    method assertTwoBatchedOk (line 336) | private void assertTwoBatchedOk(KeyProducerJavaIncremental producer, i...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaRandomTest.java
  class KeyProducerJavaRandomTest (line 44) | @RunWith(DataProviderRunner.class)
    method setUp (line 54) | @Before
    method createKeyProducerJavaRandom (line 59) | private KeyProducerJavaRandom createKeyProducerJavaRandom(CKeyProducer...
    method createSecrets_parameterBatchSizeInBitsZeroAndReturnStartSecretOnlyTrue_returnExpectedSecrets (line 64) | @Test
    method createSecrets_parameterBatchSizeInBitsFromDataProviderAndReturnStartSecretOnlyTrue_returnExpectedSecrets (line 84) | @Test
    method createSecrets_parameterBatchSizeInBitsFromDataProviderAndReturnStartSecretOnlyFalse_returnExpectedSecrets (line 105) | @Test
    method generateSecrets (line 128) | private BigInteger[] generateSecrets(CKeyProducerJavaRandomInstance in...
    method testSecureRandom (line 138) | @Test
    method testRandomSeedCurrentTimeMillis (line 144) | @Test
    method testRandomCustomSeed_default (line 150) | @Test
    method testRandomCustomSeed_fixed (line 156) | @Test
    method testSha1Prng_default (line 162) | @Test
    method testSha1Prng_fixed (line 168) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaSocketTest.java
  class KeyProducerJavaSocketTest (line 54) | @RunWith(DataProviderRunner.class)
    method findFreePort (line 64) | public static int findFreePort() {
    method setup (line 72) | @Before
    method teardown (line 78) | @After
    method createServerConfig (line 83) | private CKeyProducerJavaSocket createServerConfig(int port) {
    method createClientConfig (line 90) | private CKeyProducerJavaSocket createClientConfig(String host, int por...
    method testServerReadsSecretWithoutReset (line 98) | @Test
    method openCloseConnection_serverMode_success (line 129) | @Test
    method waitUntilPortOpen (line 173) | private void waitUntilPortOpen(int timeoutMillis) throws Exception {
    method openCloseConnection_serverClient_success (line 177) | @Test
    method createSecrets_success_readsExpectedBigInteger (line 206) | @Test
    method createSecrets_prematureStreamClose_throwsException (line 238) | @Test(expected = NoMoreSecretsAvailableException.class)
    method interrupt_closesConnectionAndNoExceptionThrown (line 264) | @Test
    method createSecrets_afterClose_reconnectsAndReadsSuccessfully (line 307) | @Test
    method createSecrets_multipleSequentialCalls_readsAllSuccessfully (line 352) | @Test
    method createSecrets_connectionRetry_worksWhenServerStartsLate (line 383) | @Test
    method createSecrets_socketClosedMidRead_throwsException (line 418) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_serverDisconnectsMidTransfer_throwsException (line 444) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_zeroSecretsRequested_returnsEmptyArray (line 469) | @Test
    method createSecrets_malformedSecretStream_throwsException (line 496) | @Test(expected = NoMoreSecretsAvailableException.class)
    method testReadRetriesAndCloseCalledOnceMaxReached (line 521) | @Test
    method hangServer (line 568) | private ServerSocket hangServer(int port) throws IOException {
    method testInterruptCausesShutdownDuringConnectionAttemptOnly (line 580) | @Test(timeout = 5000)
    method serverAcceptTimesOut_whenNoClientConnects (line 628) | @Test(timeout = 5000)
    method cleanup (line 654) | private void cleanup(@Nullable KeyProducerJavaSocket client, @Nullable...
    method cleanup (line 658) | private void cleanup(@Nullable KeyProducerJavaSocket client, @Nullable...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaTest.java
  class KeyProducerJavaTest (line 44) | @RunWith(DataProviderRunner.class)
    method setUp (line 59) | @Before
    method createSecrets_throwsException_whenWorkSizeExceedsMax (line 66) | @Test
    method createSecrets_throwsException_whenWorkSizeTooLess (line 77) | @Test
    method createKeyProducer (line 89) | public KeyProducerJava createKeyProducer(CommonDataProvider.KeyProduce...
    method assertWorkSizeTooLargeThrows (line 123) | public static <T extends CKeyProducerJava> void assertWorkSizeTooLarge...
    method assertWorkSizeTooLessThrows (line 134) | public static <T extends CKeyProducerJava> void assertWorkSizeTooLessT...
    method configureKeyProducerJavaRandom (line 145) | private CKeyProducerJavaRandom configureKeyProducerJavaRandom(String k...
    method configureKeyProducerJavaIncremental (line 154) | private CKeyProducerJavaIncremental configureKeyProducerJavaIncrementa...
    method configureKeyProducerJavaBip39 (line 161) | private CKeyProducerJavaBip39 configureKeyProducerJavaBip39(String key...
    method configureKeyProducerJavaSocket (line 169) | private CKeyProducerJavaSocket configureKeyProducerJavaSocket(String k...
    method configureKeyProducerJavaWebSocket (line 178) | private CKeyProducerJavaWebSocket configureKeyProducerJavaWebSocket(St...
    method configureKeyProducerJavaZmq (line 187) | private CKeyProducerJavaZmq configureKeyProducerJavaZmq(String keyProd...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaWebSocketTest.java
  class KeyProducerJavaWebSocketTest (line 43) | public class KeyProducerJavaWebSocketTest {
    method setUp (line 51) | @Before
    method tearDown (line 60) | @After
    method createConfig (line 65) | private CKeyProducerJavaWebSocket createConfig() {
    method createSecrets_receivesValidSecret (line 72) | @Test
    method createSecrets_timeoutWithoutMessage_throwsException (line 103) | @Test(expected = NoMoreSecretsAvailableException.class)
    method interrupt_stopsReceiverAndCausesNoMoreSecretsAvailableException (line 112) | @Test
    method createSecrets_invalidMessageLength_ignoredByServer (line 132) | @Test
    method waitForConnectionOrFail (line 164) | public static void waitForConnectionOrFail(WebSocketClient client, Cou...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaZmqTest.java
  class KeyProducerJavaZmqTest (line 48) | public class KeyProducerJavaZmqTest {
    method setup (line 56) | @Before
    method teardown (line 62) | @After
    method createKeyProducerJavaZmq (line 67) | private KeyProducerJavaZmq createKeyProducerJavaZmq(CKeyProducerJavaZm...
    method findFreeZmqAddress (line 71) | public static String findFreeZmqAddress() {
    method createBindConfig (line 75) | private CKeyProducerJavaZmq createBindConfig(String address) {
    method createConnectConfig (line 82) | private CKeyProducerJavaZmq createConnectConfig(String address) {
    method createSecrets_connectMode_receivesSecret (line 90) | @Test
    method createSecrets_success_receivesOneKey (line 126) | @Test
    method createSecrets_timeout_throwsException (line 168) | @Test(expected = NoMoreSecretsAvailableException.class)
    method createSecrets_multipleKeys_success (line 182) | @Test
    method createSecrets_invalidSecretLength_errorLogged (line 236) | @Test
    method interrupt_duringReceive_stopsCleanly (line 282) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerTestUtility.java
  class KeyProducerTestUtility (line 36) | public class KeyProducerTestUtility {
    method createZeroedSecret (line 47) | public byte[] createZeroedSecret() {
    method createFilledSecret (line 60) | public byte[] createFilledSecret(byte fillByte) {
    method createIncrementedSecret (line 81) | public byte[] createIncrementedSecret(byte startByte) {
    method assertIncrementedSecrets (line 97) | public void assertIncrementedSecrets(BigInteger[] secrets) {
    method assertFilledSecret (line 123) | public void assertFilledSecret(BigInteger secret, byte fillByte) {
    method createInvalidSecret (line 151) | public byte[] createInvalidSecret() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/NoMoreSecretsAvailableExceptionTest.java
  class NoMoreSecretsAvailableExceptionTest (line 32) | public class NoMoreSecretsAvailableExceptionTest {
    method constructor_noArg_isInstanceOfRuntimeException (line 35) | @Test
    method constructor_noArg_nullMessage (line 44) | @Test
    method constructor_noArg_noCause (line 53) | @Test
    method constructor_withMessage_messageIsPreserved (line 62) | @Test
    method constructor_withMessage_noCause (line 74) | @Test
    method constructor_withMessageAndCause_messageIsPreserved (line 86) | @Test
    method constructor_withMessageAndCause_causeIsPreserved (line 99) | @Test
    method constructor_withCause_causeIsPreserved (line 112) | @Test
    method constructor_withCause_messageContainsCauseMessage (line 124) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/keyproducer/TestTimeProvider.java
  class TestTimeProvider (line 23) | public class TestTimeProvider {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/persistence/PersistenceUtilsTest.java
  class PersistenceUtilsTest (line 32) | public class PersistenceUtilsTest {
    method longToByteBufferDirect_zeroValue_returnsNotNull (line 38) | @Test
    method longToByteBufferDirect_zeroValue_returnsSameInstanceOnRepeatedCalls (line 47) | @Test
    method longToByteBufferDirect_zeroValue_capacityIsLongBytes (line 57) | @Test
    method longToByteBufferDirect_zeroValue_absoluteGetLongReturnsZero (line 66) | @Test
    method longToByteBufferDirect_positiveValue_returnsNotNull (line 77) | @Test
    method longToByteBufferDirect_positiveValue_capacityIsLongBytes (line 86) | @Test
    method longToByteBufferDirect_positiveValue_absoluteGetLongReturnsCorrectValue (line 95) | @Test
    method longToByteBufferDirect_positiveValue_remainingIsLongBytes (line 107) | @Test
    method longToByteBufferDirect_negativeValue_absoluteGetLongReturnsCorrectValue (line 118) | @Test
    method longToByteBufferDirect_negativeValue_capacityIsLongBytes (line 130) | @Test
    method longToByteBufferDirect_longMaxValue_absoluteGetLongReturnsMaxValue (line 141) | @Test
    method longToByteBufferDirect_longMinValue_absoluteGetLongReturnsMinValue (line 153) | @Test
    method longToByteBufferDirect_oneValue_absoluteGetLongReturnsOne (line 165) | @Test
    method longToByteBufferDirect_nonZeroValueCalledTwice_returnsDifferentInstances (line 177) | @Test
    method longToByteBufferDirect_nonZeroValueNotSameAsZeroCachedBuffer_returnsDifferentInstance (line 187) | @Test

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/AbstractTestAddresses.java
  class AbstractTestAddresses (line 36) | public abstract class AbstractTestAddresses implements TestAddresses {
    method AbstractTestAddresses (line 42) | public AbstractTestAddresses(int randomSeed, int numberOfAddresses, bo...
    method getNumberOfAddresses (line 51) | @Override
    method getECKeys (line 56) | @Override
    method toLegacyAddress (line 61) | private LegacyAddress toLegacyAddress(ECKey ecKey) {
    method getLegacyAddressAtIndex (line 65) | private LegacyAddress getLegacyAddressAtIndex(int index) {
    method getIndexAsBase58String (line 70) | @Override
    method getIndexAsHash160 (line 76) | @Override
    method getIndexAsHash160HexEncoded (line 82) | @Override
    method getIndexAsHash160ByteBuffer (line 88) | @Override
    method getAsBase58Strings (line 96) | @Override
    method getAsBase58StringList (line 107) | @Override

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/AddressesFileSpecialUsecases.java
  class AddressesFileSpecialUsecases (line 32) | public class AddressesFileSpecialUsecases implements AddressesFiles {
    method AddressesFileSpecialUsecases (line 40) | public AddressesFileSpecialUsecases() {
    method createAddressesFiles (line 44) | @Override
    method getAllAddresses (line 57) | public List<String> getAllAddresses() {
    method getTestAddresses (line 65) | @Override

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/AddressesFiles.java
  type AddressesFiles (line 25) | public interface AddressesFiles {
    method createAddressesFiles (line 27) | List<String> createAddressesFiles(TemporaryFolder folder, boolean addI...
    method getTestAddresses (line 29) | TestAddresses getTestAddresses();

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/StaticAddressesFiles.java
  class StaticAddressesFiles (line 32) | public class StaticAddressesFiles implements AddressesFiles {
    method StaticAddressesFiles (line 38) | public StaticAddressesFiles() {
    method createAddressesFiles (line 41) | @Override
    method getSupportedAddresses (line 51) | public List<String> getSupportedAddresses() {
    method getAllAddresses (line 59) | public List<String> getAllAddresses() {
    method getUnsupportedAddresses (line 66) | public List<String> getUnsupportedAddresses() {
    method extractAddresses (line 70) | private <T extends Enum<T> & PublicAddress> List<String> extractAddres...
    method getTestAddresses (line 76) | @Override

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/StaticKey.java
  class StaticKey (line 28) | public class StaticKey {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/TestAddresses.java
  type TestAddresses (line 25) | public interface TestAddresses {
    method getNumberOfAddresses (line 27) | int getNumberOfAddresses();
    method getECKeys (line 29) | List<ECKey> getECKeys();
    method getAsBase58Strings (line 31) | String getAsBase58Strings();
    method getAsBase58StringList (line 33) | List<String> getAsBase58StringList();
    method getIndexAsBase58String (line 35) | String getIndexAsBase58String(int index);
    method getIndexAsHash160HexEncoded (line 37) | String getIndexAsHash160HexEncoded(int index);
    method getIndexAsHash160 (line 39) | byte[] getIndexAsHash160(int index);
    method getIndexAsHash160ByteBuffer (line 41) | ByteBuffer getIndexAsHash160ByteBuffer(int index);

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/TestAddresses1337.java
  class TestAddresses1337 (line 21) | public class TestAddresses1337 extends AbstractTestAddresses {
    method TestAddresses1337 (line 25) | public TestAddresses1337(int numberOfAddresses, boolean compressed) {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/TestAddresses42.java
  class TestAddresses42 (line 21) | public class TestAddresses42 extends AbstractTestAddresses {
    method TestAddresses42 (line 25) | public TestAddresses42(int numberOfAddresses, boolean compressed) {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/TestAddressesFiles.java
  class TestAddressesFiles (line 36) | public class TestAddressesFiles implements AddressesFiles {
    method TestAddressesFiles (line 96) | public TestAddressesFiles(boolean compressed) {
    method addFormattedAddresses (line 193) | private void addFormattedAddresses(
    method createAddressesFiles (line 219) | @Override
    method getTestAddresses (line 257) | @Override

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/TestAddressesLMDB.java
  class TestAddressesLMDB (line 29) | public class TestAddressesLMDB {
    method createTestLMDB (line 32) | public File createTestLMDB(TemporaryFolder folder, AddressesFiles addr...

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/enums/P2PKH.java
  type P2PKH (line 28) | public enum P2PKH implements PublicAddress {
    method P2PKH (line 594) | P2PKH(String publicAddress, String publicKeyHash) {
    method getPublicAddress (line 599) | @Override
    method getPublicKeyHashAsHex (line 604) | public String getPublicKeyHashAsHex() {
    method getPublicKeyHash (line 608) | public byte[] getPublicKeyHash() {
    method getPublicKeyHashAsByteBuffer (line 612) | public ByteBuffer getPublicKeyHashAsByteBuffer() {
    method getPublicKeyHashAsBase58 (line 616) | public String getPublicKeyHashAsBase58() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/enums/P2SH.java
  type P2SH (line 28) | public enum P2SH implements PublicAddress {
    method P2SH (line 109) | P2SH(String publicAddress, String scriptHash) {
    method getPublicAddress (line 114) | @Override
    method getScriptHashAsHex (line 119) | public String getScriptHashAsHex() {
    method getScriptHash (line 123) | public byte[] getScriptHash() {
    method getScriptHashAsByteBuffer (line 127) | public ByteBuffer getScriptHashAsByteBuffer() {
    method getScriptHashAsBase58 (line 131) | private String getScriptHashAsBase58() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/enums/P2WPKH.java
  type P2WPKH (line 29) | public enum P2WPKH implements PublicAddress {
    method P2WPKH (line 177) | P2WPKH(String publicAddress, String witnessProgramAsHex) {
    method getPublicAddress (line 182) | @Override
    method getWitnessProgramAsHex (line 187) | public String getWitnessProgramAsHex() {
    method getWitnessProgram (line 191) | public byte[] getWitnessProgram() {
    method getWitnessProgramAsByteBuffer (line 195) | public ByteBuffer getWitnessProgramAsByteBuffer() {
    method getWitnessProgramAsBase58 (line 199) | public String getWitnessProgramAsBase58() {

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/enums/PublicAddress.java
  type PublicAddress (line 21) | public interface PublicAddress {
    method getPublicAddress (line 27) | String getPublicAddress();

FILE: src/test/java/net/ladenthin/bitcoinaddressfinder/staticaddresses/enums/StaticUnsupportedAddress.java
  type StaticUnsupportedAddress (line 21) | public enum StaticUnsupportedAddress implements PublicAddress {
    method StaticUnsupportedAddress (line 116) | StaticUnsupportedAddress(String publicAddress) {
    method getPublicAddress (line 120) | @Override
Condensed preview — 284 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,775K chars).
[
  {
    "path": ".claude/skills/java-tdd-guide/SKILL.md",
    "chars": 27884,
    "preview": "---\nname: java-tdd-guide\ndescription: Bernard Ladenthin's personal Java Test-Driven Development skill — version 1.0.0 — "
  },
  {
    "path": ".claude/skills/tdd/SKILL.md",
    "chars": 1695,
    "preview": "---\nname: tdd\ndescription: Test-Driven Development workflow for BitcoinAddressFinder — delegates to the generic Java TDD"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 527,
    "preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
  },
  {
    "path": ".github/workflows/assembly.yml",
    "chars": 1051,
    "preview": "name: build assembly\n\non:\n  push:\n    branches:\n      - main\n      - 'releases/*'\n  pull_request:\n    branches:\n      - "
  },
  {
    "path": ".github/workflows/claude-code-review.yml",
    "chars": 1433,
    "preview": "name: Claude Code Review\n\non:\n  pull_request:\n    types: [opened, synchronize, ready_for_review, reopened]\n    # Optiona"
  },
  {
    "path": ".github/workflows/claude.yml",
    "chars": 1886,
    "preview": "name: Claude Code\n\non:\n  issue_comment:\n    types: [created]\n  pull_request_review_comment:\n    types: [created]\n  issue"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "chars": 1113,
    "preview": "name: \"CodeQL\"\n\non:\n  push:\n    branches: [ \"main\" ]\n  pull_request:\n    branches: [ \"main\" ]\n  schedule:\n    - cron: \"1"
  },
  {
    "path": ".github/workflows/coverage.yml",
    "chars": 1645,
    "preview": "name: code coverage\n\non:\n  push:\n    branches:\n      - main\n      - 'releases/*'\n  pull_request:\n    branches:\n      - '"
  },
  {
    "path": ".github/workflows/matrixci.yml",
    "chars": 1975,
    "preview": "name: matrix CI\n\non:\n  push:\n    branches:\n      - main\n      - 'releases/*'\n  pull_request:\n    branches:\n      - '*'\n\n"
  },
  {
    "path": ".gitignore",
    "chars": 439,
    "preview": "# Compiled class file\r\n*.class\r\n\r\n# Log file\r\n*.log\r\n\r\n# BlueJ files\r\n*.ctxt\r\n\r\n# Mobile Tools for Java (J2ME)\r\n.mtj.tmp"
  },
  {
    "path": ".mvn/jvm.config",
    "chars": 646,
    "preview": "--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED\n--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-U"
  },
  {
    "path": "CLAUDE.md",
    "chars": 17543,
    "preview": "# CLAUDE.md — BitcoinAddressFinder\r\n\r\nThis document provides guidance for AI assistants working on the BitcoinAddressFin"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5267,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CODE_WRITING_GUIDE.md",
    "chars": 2557,
    "preview": "# Code Writing Guide — BitcoinAddressFinder (Project-Specific Supplement)\n\nThis guide contains **project-specific** prod"
  },
  {
    "path": "LICENSE",
    "chars": 16222,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 83950,
    "preview": "# BitcoinAddressFinder\n> 🚀 Fast address finder for Bitcoin and altcoins using OpenCL & Java – includes vanity address ge"
  },
  {
    "path": "TEST_WRITING_GUIDE.md",
    "chars": 5722,
    "preview": "# Unit Test Writing Guide — BitcoinAddressFinder (Project-Specific Supplement)\n\nThis guide contains **project-specific**"
  },
  {
    "path": "build.bat",
    "chars": 53,
    "preview": "call mvn clean\r\ncall mvn compile test assembly:single"
  },
  {
    "path": "examples/addresses/fileContainingAddresses0.txt",
    "chars": 163,
    "preview": "# comment\r\n12R4kPeSK6i9427ctH15j2NcJ1ST1FT21C,0\r\n13z55AGS14pSPiPpMqAAFHb576tSmSmR77,1\r\n14rDamyE53BNLPSj4cku6ZXiW6xbBdMJ9"
  },
  {
    "path": "examples/addresses/fileContainingAddresses1.tsv",
    "chars": 134,
    "preview": "# comment\r\n15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC;1337\r\n17LYqSzhuWksgoGsgakiWBG8PmbCKyrrac;1337\r\n17RTTUAiiPqUTKtEggJPec8RxLM"
  },
  {
    "path": "examples/addresses/fileContainingAddresses2.csv",
    "chars": 119,
    "preview": "# comment\r\n17aDRzRQK8ccBLVBzsms3ZasVKc9q3o3Qk\r\n18LDvu2nqr8a5AK9AHkkqDK6Z65dzbTgtn\r\n1966U1pjj15tLxPXZ19U48c99EJDkdXeqb\r\n"
  },
  {
    "path": "examples/config_AddressFilesToLMDB.json",
    "chars": 700,
    "preview": "{\r\n  \"command\": \"AddressFilesToLMDB\",\r\n  \"addressFilesToLMDB\": {\r\n    \"addressesFiles\": [\r\n      \"addresses/fileContaini"
  },
  {
    "path": "examples/config_Find_1OpenCLDevice.json",
    "chars": 3029,
    "preview": "{\r\n  \"command\": \"Find\",\r\n  \"finder\": {\r\n    \"keyProducerJavaIncremental\": [\r\n        {\r\n            \"keyProducerId\": \"ex"
  },
  {
    "path": "examples/config_Find_1OpenCLDeviceAnd2CPUProducer.json",
    "chars": 2185,
    "preview": "{\r\n  \"command\": \"Find\",\r\n  \"finder\": {\r\n    \"keyProducerJavaRandom\": [\r\n      {\r\n        \"keyProducerId\": \"exampleKeyPro"
  },
  {
    "path": "examples/config_Find_8CPUProducer.json",
    "chars": 4038,
    "preview": "{\r\n  \"command\": \"Find\",\r\n  \"finder\": {\r\n    \"keyProducerJavaRandom\": [\r\n      {\r\n        \"keyProducerId\": \"exampleKeyPro"
  },
  {
    "path": "examples/config_Find_SecretsFile.json",
    "chars": 1866,
    "preview": "{\r\n  \"command\": \"Find\",\r\n  \"finder\": {\r\n    \"keyProducerJavaRandom\": [],\r\n    \"consumerJava\": {\r\n      \"lmdbConfiguratio"
  },
  {
    "path": "examples/config_LMDBToAddressFile.json",
    "chars": 320,
    "preview": "{\r\n  \"command\": \"LMDBToAddressFile\",\r\n  \"lmdbToAddressFile\": {\r\n    \"lmdbConfigurationReadOnly\": {\r\n      \"lmdbDirectory"
  },
  {
    "path": "examples/config_OpenCLInfo.json",
    "chars": 31,
    "preview": "{\r\n  \"command\": \"OpenCLInfo\"\r\n}"
  },
  {
    "path": "examples/logbackConfiguration.xml",
    "chars": 414,
    "preview": "<configuration>\r\n  <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\r\n    <!-- encoders are assigned "
  },
  {
    "path": "examples/run_AddressFilesToLMDB.bat",
    "chars": 612,
    "preview": "rem start /low java ^\r\njava ^\r\n--add-opens java.base/java.lang=ALL-UNNAMED ^\r\n--add-opens java.base/java.io=ALL-UNNAMED "
  },
  {
    "path": "examples/run_Find_1OpenCLDevice.bat",
    "chars": 611,
    "preview": "rem start /low java ^\r\njava ^\r\n--add-opens java.base/java.lang=ALL-UNNAMED ^\r\n--add-opens java.base/java.io=ALL-UNNAMED "
  },
  {
    "path": "examples/run_Find_1OpenCLDeviceAnd2CPUProducer.bat",
    "chars": 641,
    "preview": "rem start /low java ^\r\njava ^\r\n--add-opens java.base/java.lang=ALL-UNNAMED ^\r\n--add-opens java.base/java.io=ALL-UNNAMED "
  },
  {
    "path": "examples/run_Find_8CPUProducer.bat",
    "chars": 609,
    "preview": "rem start /low java ^\r\njava ^\r\n--add-opens java.base/java.lang=ALL-UNNAMED ^\r\n--add-opens java.base/java.io=ALL-UNNAMED "
  },
  {
    "path": "examples/run_Find_SecretsFile.bat",
    "chars": 607,
    "preview": "rem start /low java ^\r\njava ^\r\n--add-opens java.base/java.lang=ALL-UNNAMED ^\r\n--add-opens java.base/java.io=ALL-UNNAMED "
  },
  {
    "path": "examples/run_LMDBToAddressFile.bat",
    "chars": 610,
    "preview": "rem start /low java ^\r\njava ^\r\n--add-opens java.base/java.lang=ALL-UNNAMED ^\r\n--add-opens java.base/java.io=ALL-UNNAMED "
  },
  {
    "path": "examples/run_OpenCLInfo.bat",
    "chars": 596,
    "preview": "rem start /low java ^\r\njava ^\r\n--add-opens java.base/java.lang=ALL-UNNAMED ^\r\n--add-opens java.base/java.io=ALL-UNNAMED "
  },
  {
    "path": "examples/secrets/fileContainingSecrets_BIG_INTEGER.txt",
    "chars": 237,
    "preview": "72155939486846849509759369733266486982821795810448245423168957390607644363272\r\n39929263256442288830290225612580366403172"
  },
  {
    "path": "examples/secrets/fileContainingSecrets_DUMPED_RIVATE_KEY.txt",
    "chars": 159,
    "preview": "5K2YUVmWfxbmvsNxCsfvArXdGXm7d5DC9pn4yD75k2UaSYgkXTh\r\n5JVAXLpkZ21svEzwyimMHn5hAkWNqJq8uGxqUqcRrNb8F4Csp8V\r\n5JXYuGrwSbyp8s"
  },
  {
    "path": "examples/secrets/fileContainingSecrets_SHA256.txt",
    "chars": 198,
    "preview": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08\r\n58472980a1d3449939eadc2652370972d5007fa9c059ce84fb3ab9"
  },
  {
    "path": "examples/secrets/fileContainingSecrets_STRING_DO_SHA256.txt",
    "chars": 29,
    "preview": "test\r\ntest with space\r\n1337\r\n"
  },
  {
    "path": "examples/websocket.html",
    "chars": 5804,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, "
  },
  {
    "path": "helper/bitinfocharts_com_scraping/scraping.py",
    "chars": 5380,
    "preview": "#\r\n# Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n#\r\n# Licensed under the Apache License, Version 2.0 ("
  },
  {
    "path": "helper/bitinfocharts_com_scraping/start.bat",
    "chars": 18,
    "preview": "python scraping.py"
  },
  {
    "path": "helper/dumpwallet/dumpwallet.py",
    "chars": 1576,
    "preview": "#!/usr/bin/python3\r\n#\r\n# Author......: Bernard Ladenthin, 2020\r\n# License.....: MIT\r\n#\r\nimport sys\r\nimport struct\r\nfrom "
  },
  {
    "path": "pom.xml",
    "chars": 14714,
    "preview": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:sc"
  },
  {
    "path": "skills/tdd.md",
    "chars": 6806,
    "preview": "# TDD Skill — BitcoinAddressFinder\r\n\r\nThis skill documents **test-driven development practices and refactoring patterns*"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/AbstractPlaintextFile.java",
    "chars": 2766,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2021 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/AbstractProducer.java",
    "chars": 7456,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/AddressFile.java",
    "chars": 2150,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/AddressFilesToLMDB.java",
    "chars": 5617,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/AddressFormatNotAcceptedException.java",
    "chars": 1278,
    "preview": "// @formatter:off\n/**\n * Copyright 2026 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/AddressToCoin.java",
    "chars": 1648,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/AddressTxtLine.java",
    "chars": 14513,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/AddressType.java",
    "chars": 1974,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/BIP39KeyProducer.java",
    "chars": 3097,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/BIP39Wordlist.java",
    "chars": 4763,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/Base36Decoder.java",
    "chars": 2236,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/Bech32Helper.java",
    "chars": 7472,
    "preview": "// @formatter:off\n/**\n * Copyright 2026 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/BitHelper.java",
    "chars": 1532,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ByteBufferUtility.java",
    "chars": 7598,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ByteConversion.java",
    "chars": 974,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/Consumer.java",
    "chars": 901,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ConsumerJava.java",
    "chars": 18144,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/EndiannessConverter.java",
    "chars": 2452,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/FileHelper.java",
    "chars": 1672,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2021 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/Finder.java",
    "chars": 12143,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/Interruptable.java",
    "chars": 792,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2021 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/KeyUtility.java",
    "chars": 9423,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/LMDBToAddressFile.java",
    "chars": 2706,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/NetworkParameterFactory.java",
    "chars": 1170,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/OpenCLContext.java",
    "chars": 9038,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/OpenCLGridResult.java",
    "chars": 7886,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/OpenClTask.java",
    "chars": 15424,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/PrivateKeyTooLargeException.java",
    "chars": 2347,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/PrivateKeyValidator.java",
    "chars": 5418,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/Producer.java",
    "chars": 2142,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerJava.java",
    "chars": 2916,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerJavaSecretsFiles.java",
    "chars": 3957,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2021 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerOpenCL.java",
    "chars": 5804,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerState.java",
    "chars": 818,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ProducerStateProvider.java",
    "chars": 808,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/PublicKeyBytes.java",
    "chars": 27664,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/RandomSecretSupplier.java",
    "chars": 1071,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ReadStatistic.java",
    "chars": 2133,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/ReleaseCLObject.java",
    "chars": 2145,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/SecretSupplier.java",
    "chars": 967,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/SecretsFile.java",
    "chars": 2857,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2021 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/SeparatorFormat.java",
    "chars": 6613,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/Shutdown.java",
    "chars": 786,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/Statistics.java",
    "chars": 1919,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/cli/Main.java",
    "chars": 11045,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CAddressFileOutputFormat.java",
    "chars": 1350,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CAddressFilesToLMDB.java",
    "chars": 1174,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CCommand.java",
    "chars": 834,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CConfiguration.java",
    "chars": 1043,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CConsumerJava.java",
    "chars": 2192,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CFinder.java",
    "chars": 1685,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJava.java",
    "chars": 1669,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaBip39.java",
    "chars": 3314,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaIncremental.java",
    "chars": 1358,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaRandom.java",
    "chars": 1593,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaRandomInstance.java",
    "chars": 2597,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaReceiver.java",
    "chars": 901,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaSocket.java",
    "chars": 2004,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaWebSocket.java",
    "chars": 916,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CKeyProducerJavaZmq.java",
    "chars": 2008,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CLMDBConfigurationReadOnly.java",
    "chars": 3726,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CLMDBConfigurationWrite.java",
    "chars": 1970,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CLMDBToAddressFile.java",
    "chars": 1035,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CProducer.java",
    "chars": 1686,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CProducerJava.java",
    "chars": 797,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CProducerJavaSecretsFiles.java",
    "chars": 1137,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2021 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CProducerOpenCL.java",
    "chars": 2841,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/CSecretFormat.java",
    "chars": 2102,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/configuration/UnknownSecretFormatException.java",
    "chars": 1480,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/eckey/Secp256k1.java",
    "chars": 6726,
    "preview": "package net.ladenthin.bitcoinaddressfinder.eckey;\r\n\r\nimport java.math.BigInteger;\r\nimport java.security.GeneralSecurityE"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/AbstractKeyProducer.java",
    "chars": 821,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/AbstractKeyProducerQueueBuffered.java",
    "chars": 4175,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/ConnectionUtils.java",
    "chars": 1415,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducer.java",
    "chars": 1038,
    "preview": "// @formatter:off\n/**\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerIdIsNotUniqueException.java",
    "chars": 1311,
    "preview": "// @formatter:off\n/**\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerIdNullException.java",
    "chars": 1166,
    "preview": "// @formatter:off\n/**\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerIdUnknownException.java",
    "chars": 1369,
    "preview": "// @formatter:off\n/**\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJava.java",
    "chars": 1527,
    "preview": "// @formatter:off\n/**\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaBip39.java",
    "chars": 2475,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaIncremental.java",
    "chars": 2588,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaRandom.java",
    "chars": 3988,
    "preview": "// @formatter:off\n/**\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaSocket.java",
    "chars": 5199,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaWebSocket.java",
    "chars": 3658,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/KeyProducerJavaZmq.java",
    "chars": 3309,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/keyproducer/NoMoreSecretsAvailableException.java",
    "chars": 1560,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLBuilder.java",
    "chars": 16471,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2022 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLDevice.java",
    "chars": 10445,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2022 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLDeviceSelection.java",
    "chars": 923,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLPlatform.java",
    "chars": 1793,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2022 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLPlatformSelector.java",
    "chars": 2274,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/persistence/Persistence.java",
    "chars": 2448,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/persistence/PersistenceUtils.java",
    "chars": 3049,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/java/net/ladenthin/bitcoinaddressfinder/persistence/lmdb/LMDBPersistence.java",
    "chars": 21141,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_common.cl",
    "chars": 2393157,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#include \"inc_vendor.h\"\n#include \"inc_types.h\"\n#incl"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_common.h",
    "chars": 27400,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#ifndef INC_COMMON_H\n#define INC_COMMON_H\n\n/*\n * Pro"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_ecc_secp256k1.cl",
    "chars": 53464,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n *\n * Furthermore, since elliptic curve operations are hi"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_ecc_secp256k1.h",
    "chars": 9777,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#ifndef INC_ECC_SECP256K1_H\n#define INC_ECC_SECP256K"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_hash_ripemd160.cl",
    "chars": 72926,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#include \"inc_vendor.h\"\n#include \"inc_types.h\"\n#incl"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_hash_ripemd160.h",
    "chars": 7991,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#ifndef INC_HASH_RIPEMD160_H\n#define INC_HASH_RIPEMD"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_hash_sha256.cl",
    "chars": 51998,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#include \"inc_vendor.h\"\n#include \"inc_types.h\"\n#incl"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_hash_sha256.h",
    "chars": 7650,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#ifndef INC_HASH_SHA256_H\n#define INC_HASH_SHA256_H\n"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_platform.cl",
    "chars": 7377,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#include \"inc_vendor.h\"\n#include \"inc_types.h\"\n#incl"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_platform.h",
    "chars": 3477,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#ifndef INC_PLATFORM_H\n#define INC_PLATFORM_H\n\nDECLS"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_types.h",
    "chars": 90087,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#ifndef INC_TYPES_H\n#define INC_TYPES_H\n\n#if ATTACK_"
  },
  {
    "path": "src/main/resources/copyfromhashcat/inc_vendor.h",
    "chars": 3957,
    "preview": "/**\n * Author......: See docs/credits.txt\n * License.....: MIT\n */\n\n#ifndef INC_VENDOR_H\n#define INC_VENDOR_H\n\n#if defin"
  },
  {
    "path": "src/main/resources/inc_defines.h",
    "chars": 154,
    "preview": "#define KERNEL_STATIC\n#define DGST_ELEM 4\n#define DGST_R0 0\n#define DGST_R1 1\n#define DGST_R2 2\n#define DGST_R3 3\n#defin"
  },
  {
    "path": "src/main/resources/inc_ecc_secp256k1custom.cl",
    "chars": 31885,
    "preview": "/**\n * Author......: Bernard Ladenthin, 2020\n * License.....: MIT\n */\n/*\n// example private key (in)\n// hex: 68e23530deb"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/chinese_simplified.txt",
    "chars": 4096,
    "preview": "的\n一\n是\n在\n不\n了\n有\n和\n人\n这\n中\n大\n为\n上\n个\n国\n我\n以\n要\n他\n时\n来\n用\n们\n生\n到\n作\n地\n于\n出\n就\n分\n对\n成\n会\n可\n主\n发\n年\n动\n同\n工\n也\n能\n下\n过\n子\n说\n产\n种\n面\n而\n方\n后\n多\n定\n行\n学\n法\n所\n"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/chinese_traditional.txt",
    "chars": 4096,
    "preview": "的\n一\n是\n在\n不\n了\n有\n和\n人\n這\n中\n大\n為\n上\n個\n國\n我\n以\n要\n他\n時\n來\n用\n們\n生\n到\n作\n地\n於\n出\n就\n分\n對\n成\n會\n可\n主\n發\n年\n動\n同\n工\n也\n能\n下\n過\n子\n說\n產\n種\n面\n而\n方\n後\n多\n定\n行\n學\n法\n所\n"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/czech.txt",
    "chars": 14945,
    "preview": "abdikace\nabeceda\nadresa\nagrese\nakce\naktovka\nalej\nalkohol\namputace\nananas\nandulka\nanekdota\nanketa\nantika\nanulovat\narcha\na"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/english.txt",
    "chars": 13116,
    "preview": "abandon\nability\nable\nabout\nabove\nabsent\nabsorb\nabstract\nabsurd\nabuse\naccess\naccident\naccount\naccuse\nachieve\nacid\nacousti"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/french.txt",
    "chars": 16389,
    "preview": "abaisser\nabandon\nabdiquer\nabeille\nabolir\naborder\naboutir\naboyer\nabrasif\nabreuver\nabriter\nabroger\nabrupt\nabsence\nabsolu\na"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/italian.txt",
    "chars": 16033,
    "preview": "abaco\nabbaglio\nabbinato\nabete\nabisso\nabolire\nabrasivo\nabrogato\naccadere\naccenno\naccusato\nacetone\nachille\nacido\nacqua\nacr"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/japanese.txt",
    "chars": 10173,
    "preview": "あいこくしん\nあいさつ\nあいだ\nあおぞら\nあかちゃん\nあきる\nあけがた\nあける\nあこがれる\nあさい\nあさひ\nあしあと\nあじわう\nあずかる\nあずき\nあそぶ\nあたえる\nあたためる\nあたりまえ\nあたる\nあつい\nあつかう\nあっしゅく"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/korean.txt",
    "chars": 13976,
    "preview": "가격\n가끔\n가난\n가능\n가득\n가르침\n가뭄\n가방\n가상\n가슴\n가운데\n가을\n가이드\n가입\n가장\n가정\n가족\n가죽\n각오\nᄀ"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/portuguese.txt",
    "chars": 15671,
    "preview": "abacate\nabaixo\nabalar\nabater\nabduzir\nabelha\naberto\nabismo\nabotoar\nabranger\nabreviar\nabrigar\nabrupto\nabsinto\nabsoluto\nabs"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/russian.txt",
    "chars": 14571,
    "preview": "абзац\nабонент\nабсурд\nавангард\nавария\nавгуст\nавиация\nавтор\nагент\nагитация\nагрегат\nадвокат\nадмирал\nадрес\nазарт\nазот\nакадем"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/spanish.txt",
    "chars": 13659,
    "preview": "ábaco\nabdomen\nabeja\nabierto\nabogado\nabono\naborto\nabrazo\nabrir\nabuelo\nabuso\nacabar\nacademia\nacceso\nacción\naceite\nacelga"
  },
  {
    "path": "src/main/resources/mnemonic/wordlist/turkish.txt",
    "chars": 14995,
    "preview": "abajur\nabaküs\nabartı\nabdal\nabdest\nabiye\nabluka\nabone\nabsorbe\nabsürt\nacayip\nacele\nacemi\naçıkgöz\nadalet\nadam\nadezyon\na"
  },
  {
    "path": "src/main/resources/simplelogger.properties",
    "chars": 1644,
    "preview": "# SLF4J's SimpleLogger configuration file\r\n# Simple implementation of Logger that sends all enabled log messages, for al"
  },
  {
    "path": "src/main/resources/unused/calc_addrs.cl",
    "chars": 36553,
    "preview": "/*\n * Vanitygen, vanity bitcoin address generator\n * Copyright (C) 2011 <samr7@cs.washington.edu>\n *\n * Vanitygen is fre"
  },
  {
    "path": "src/main/resources/unused/calc_addrs_fix_zero.cl",
    "chars": 36561,
    "preview": "/*\n * Vanitygen, vanity bitcoin address generator\n * Copyright (C) 2011 <samr7@cs.washington.edu>\n *\n * Vanitygen is fre"
  },
  {
    "path": "src/main/resources/unused/gpu.cl",
    "chars": 32114,
    "preview": "/*\n * OCLExplorer bitcoin addresses brute-force tool\n * Copyright (C) 2017 Stanislav V. Tretyakov <svtrostov@yandex.ru>\n"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AbstractPlaintextFileTest.java",
    "chars": 8811,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AbstractProducerTest.java",
    "chars": 13612,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AbstractProducerTestImpl.java",
    "chars": 1423,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AddressFileTest.java",
    "chars": 9910,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2026 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AddressFilesToLMDBTest.java",
    "chars": 8781,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2026 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AddressFormatNotAcceptedExceptionTest.java",
    "chars": 3951,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2026 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AddressToCoinTest.java",
    "chars": 3608,
    "preview": "// @formatter:off\n/**\n * Copyright 2021 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AddressTxtLineTest.java",
    "chars": 15646,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AddressTypeTest.java",
    "chars": 3257,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2026 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AwaitTimeTest.java",
    "chars": 1163,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/AwaitTimeTests.java",
    "chars": 928,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/BIP39DataProvider.java",
    "chars": 2834,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/BIP39KeyProducerTest.java",
    "chars": 7786,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/BIP39WordlistTest.java",
    "chars": 10674,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2026 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/Base36DecoderTest.java",
    "chars": 9347,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/Bech32HelperTest.java",
    "chars": 4915,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2026 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/BitHelperTest.java",
    "chars": 3416,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2024 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/ByteBufferUtilityTest.java",
    "chars": 17385,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/ByteConversionTest.java",
    "chars": 6096,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/CommonDataProvider.java",
    "chars": 35313,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/ConsumerJavaTest.java",
    "chars": 34148,
    "preview": "// @formatter:off\n/**\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/EndiannessConverterTest.java",
    "chars": 3379,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/EqualHashCodeToStringTestHelper.java",
    "chars": 4551,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2021 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/FileHelperTest.java",
    "chars": 4641,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/FinderTest.java",
    "chars": 21989,
    "preview": "// @formatter:off\n/**\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/HexEncodeTest.java",
    "chars": 1530,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/KeyUtilityTest.java",
    "chars": 28364,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/LMDBBase.java",
    "chars": 2518,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/LMDBPersistencePerformanceTest.java",
    "chars": 6607,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/LMDBPersistenceTest.java",
    "chars": 11768,
    "preview": "// @formatter:off\r\n/**\r\n * Copyright 2020 Bernard Ladenthin bernard.ladenthin@gmail.com\r\n *\r\n * Licensed under the Apach"
  },
  {
    "path": "src/test/java/net/ladenthin/bitcoinaddressfinder/LMDBPlatformAssume.java",
    "chars": 1342,
    "preview": "// @formatter:off\n/**\n * Copyright 2025 Bernard Ladenthin bernard.ladenthin@gmail.com\n *\n * Licensed under the Apache Li"
  }
]

// ... and 84 more files (download for full content)

About this extraction

This page contains the full source code of the bernardladenthin/BitcoinAddressFinder GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 284 files (4.3 MB), approximately 1.1M tokens, and a symbol index with 1528 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!