Display time to reach 50% probability
This commit is contained in:
parent
620a2c1980
commit
14b39f82ae
5 changed files with 435 additions and 16188 deletions
1
.husky/.gitignore
vendored
1
.husky/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
_
|
16486
package-lock.json
generated
16486
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -20,6 +20,7 @@
|
|||
"core-js": "^3.6.5",
|
||||
"crypto-js": "^3.3.0",
|
||||
"downloadjs": "^1.4.7",
|
||||
"humanize-duration": "^3.27.0",
|
||||
"keccak": "^3.0.1",
|
||||
"randombytes": "^2.0.6",
|
||||
"register-service-worker": "^1.7.1",
|
||||
|
@ -37,7 +38,7 @@
|
|||
"cross-env": "^7.0.3",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"husky": "^6.0.0",
|
||||
"husky": "^7.0.0",
|
||||
"prettier": "^2.2.1",
|
||||
"pretty-quick": "^3.1.0",
|
||||
"sass": "^1.26.5",
|
||||
|
|
|
@ -1,28 +1,38 @@
|
|||
<template>
|
||||
<div class="panel" id="input-panel">
|
||||
<form :class="{error: inputError}" @submit.prevent="startGen">
|
||||
<form :class="{ error: inputError }" @submit.prevent="startGen">
|
||||
<div class="error-text">Numbers and letters from A to F only</div>
|
||||
<input type="text" class="text-input-large" id="input"
|
||||
:placeholder="suffix ? 'Suffix' : 'Prefix'" v-model="hex" :disabled="running">
|
||||
<input
|
||||
type="text"
|
||||
class="text-input-large"
|
||||
id="input"
|
||||
:placeholder="suffix ? 'Suffix' : 'Prefix'"
|
||||
v-model="hex"
|
||||
:disabled="running"
|
||||
/>
|
||||
<div class="row justify-content-center hide-render">
|
||||
<div class="spinner">
|
||||
<div></div><div></div><div></div><div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="example hide-prerender">
|
||||
E.g.
|
||||
<span class="monospace">
|
||||
0x<!--
|
||||
--><b v-if="!suffix" v-text="example.chosen"></b><!--
|
||||
--><span v-text="example.random"></span><!--
|
||||
--><b v-if="!suffix" v-text="example.chosen"></b
|
||||
><!--
|
||||
--><span v-text="example.random"></span
|
||||
><!--
|
||||
--><b v-if="suffix" v-text="example.chosen"></b>
|
||||
</span>
|
||||
</div>
|
||||
<div class="row controls hide-prerender">
|
||||
<div class="col-12 col-sm-6 col-md-12 col-lg-6">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="checkbox" checked="" v-model="checksum"
|
||||
:disabled="running">
|
||||
<input type="checkbox" name="checkbox" checked="" v-model="checksum" :disabled="running" />
|
||||
<i class="left"> </i>
|
||||
Case-sensitive
|
||||
</label>
|
||||
|
@ -30,29 +40,44 @@
|
|||
<div class="col-12 col-sm-6 col-md-12 col-lg-6">
|
||||
<span>Prefix</span>
|
||||
<label class="switch">
|
||||
<input type="checkbox" v-model="suffix" :disabled="running">
|
||||
<input type="checkbox" v-model="suffix" :disabled="running" />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span>Suffix</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="threads hide-prerender">
|
||||
<input type="button" class="square-btn button-large" value="-" @click="threads--"
|
||||
:disabled="running || threads <= 1">
|
||||
<input type="button" class="square-btn arrow button-large" value="+" @click="threads++"
|
||||
:disabled="running">
|
||||
<input
|
||||
type="button"
|
||||
class="square-btn button-large"
|
||||
value="-"
|
||||
@click="threads--"
|
||||
:disabled="running || threads <= 1"
|
||||
/>
|
||||
<input
|
||||
type="button"
|
||||
class="square-btn arrow button-large"
|
||||
value="+"
|
||||
@click="threads++"
|
||||
:disabled="running"
|
||||
/>
|
||||
<h4 v-text="threads"></h4>
|
||||
<span>threads</span>
|
||||
<span> threads</span>
|
||||
<span v-if="threads === cores">(recommended)</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-sm-12">
|
||||
<input type="button" value="Generate" class="button-large hide-render" disabled>
|
||||
<input type="button" value="Generate" class="button-large hide-prerender" @click="startGen"
|
||||
:disabled="running || inputError || error">
|
||||
<input type="button" value="Generate" class="button-large hide-render" disabled />
|
||||
<input
|
||||
type="button"
|
||||
value="Generate"
|
||||
class="button-large hide-prerender"
|
||||
@click="startGen"
|
||||
:disabled="running || inputError || error"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-lg-6 col-sm-12">
|
||||
<input type="button" value="Stop" class="button-large" @click="stopGen" :disabled="!running">
|
||||
<input type="button" value="Stop" class="button-large" @click="stopGen" :disabled="!running" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -75,7 +100,7 @@
|
|||
export default {
|
||||
props: {
|
||||
running: Boolean,
|
||||
cores: Number
|
||||
cores: Number,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
|
@ -83,7 +108,7 @@
|
|||
hex: '',
|
||||
checksum: true,
|
||||
suffix: false,
|
||||
error: false
|
||||
error: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -97,10 +122,10 @@
|
|||
const chosen = this.checksum ? this.hex : mixCase(this.hex);
|
||||
let random = '';
|
||||
for (let i = 0; i < 40 - this.hex.length; i++) {
|
||||
random += mixCase(Math.floor((Math.random() * 16)).toString(16));
|
||||
random += mixCase(Math.floor(Math.random() * 16).toString(16));
|
||||
}
|
||||
return {random, chosen};
|
||||
}
|
||||
return { random, chosen };
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
startGen: function () {
|
||||
|
@ -110,7 +135,7 @@
|
|||
},
|
||||
stopGen: function () {
|
||||
this.$emit('stop');
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
hex: function () {
|
||||
|
@ -124,8 +149,8 @@
|
|||
},
|
||||
threads: function () {
|
||||
this.$emit('input-change', 'threads', this.threads);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div class="panel">
|
||||
<div>Difficulty: <span class="output" v-text="formatNum(difficulty)">1</span></div>
|
||||
<div>Generated: <span class="output"
|
||||
v-text="formatNum(count) + (count === 1 ? ' address' : ' addresses')">0 addresses</span>
|
||||
<div>
|
||||
Generated:
|
||||
<span class="output" v-text="formatNum(count) + (count === 1 ? ' address' : ' addresses')"
|
||||
>0 addresses</span
|
||||
>
|
||||
</div>
|
||||
<div>50% probability: <span class="output" v-text="probability50">0 addresses</span></div>
|
||||
<div>50% probability: <span class="output" v-text="speed ? time50 : adresses50">0 addresses</span></div>
|
||||
<div>Speed: <span class="output" v-text="speed + ' addr/s'">0 addr/s</span></div>
|
||||
<div>Status: <span class="output" v-text="status">Waiting</span></div>
|
||||
|
||||
|
@ -20,27 +23,33 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import humanizeDuration from 'humanize-duration';
|
||||
|
||||
const computeDifficulty = function (pattern, isChecksum) {
|
||||
const ret = Math.pow(16, pattern.length);
|
||||
return isChecksum ? (ret * Math.pow(2, pattern.replace(/[^a-f]/gi, '').length)) : ret;
|
||||
return isChecksum ? ret * Math.pow(2, pattern.replace(/[^a-f]/gi, '').length) : ret;
|
||||
};
|
||||
|
||||
const computeProbability = function (difficulty, attempts) {
|
||||
return 1 - Math.pow(1 - (1 / difficulty), attempts);
|
||||
return 1 - Math.pow(1 - 1 / difficulty, attempts);
|
||||
};
|
||||
|
||||
const isValidHex = function (hex) {
|
||||
return hex.length ? /^[0-9A-F]+$/g.test(hex.toUpperCase()) : true;
|
||||
};
|
||||
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
speed: 0,
|
||||
count: 0
|
||||
count: 0,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
hex: String,
|
||||
checksum: Boolean,
|
||||
status: String,
|
||||
firstTick: {}
|
||||
firstTick: {},
|
||||
},
|
||||
watch: {
|
||||
hex() {
|
||||
|
@ -48,32 +57,47 @@
|
|||
},
|
||||
checksum() {
|
||||
this.count = 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
inputError: function () {
|
||||
return !isValidHex(this.hex);
|
||||
},
|
||||
difficulty: function () {
|
||||
return this.inputError ? 'N/A' : computeDifficulty(this.hex, this.checksum);
|
||||
},
|
||||
probability50: function () {
|
||||
return this.inputError ? 'N/A' : this.formatNum(Math.floor(Math.log(0.5) / Math.log(1 - (1 / this.difficulty)))) + ' addresses';
|
||||
probability50() {
|
||||
return this.inputError ? 0 : Math.floor(Math.log(0.5) / Math.log(1 - 1 / this.difficulty));
|
||||
},
|
||||
adresses50: function () {
|
||||
if (this.probability50 === -Infinity) {
|
||||
return 'Nearly impossible';
|
||||
}
|
||||
return this.inputError ? 'N/A' : this.formatNum(this.probability50) + ' addresses';
|
||||
},
|
||||
time50: function () {
|
||||
const seconds = this.probability50 / this.speed;
|
||||
if (seconds > 200 * 365.25 * 24 * 3600 || seconds === -Infinity) {
|
||||
return 'Thousands of years';
|
||||
}
|
||||
return this.inputError ? 'N/A' : humanizeDuration(Math.round(seconds) * 1000, { largest: 2 });
|
||||
},
|
||||
probability: function () {
|
||||
return Math.round(10000 * computeProbability(this.difficulty, this.count)) / 100;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
formatNum: function (num) {
|
||||
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
|
||||
}
|
||||
},
|
||||
},
|
||||
created: function () {
|
||||
this.$parent.$on('increment-counter', (incr) => {
|
||||
this.count += (incr > 0 ? incr : -this.count);
|
||||
this.speed = incr > 0 ? Math.floor(1000 * this.count / (performance.now() - this.firstTick)) : 0;
|
||||
this.count += incr > 0 ? incr : -this.count;
|
||||
this.speed = incr > 0 ? Math.floor((1000 * this.count) / (performance.now() - this.firstTick)) : 0;
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
|
|
Loading…
Add table
Reference in a new issue