véletlen számok dash-ban hogyan?

 ( sas | 2019. február 4., hétfő - 14:25 )

Sziasztok, a témám az, hogy véletlen számokat szeretnék kapni a lehető legalacsonyabb szintű eszközökkel dash-ban, lehetőleg csak belső eszközöket használva.

egy véletlen sztringet tudok olvasni:

#/bin/dash
read adag </dev/urandom;
echo $adag

Induljunk ki abból, hogy van egy sztringem, ami 0-nál több karaktert tartalmaz

Ki milyen nagy okosságot tudna adni arra, hogy hogyan tudnék véletlen számokat kapni csak a dash belső eszközeivel?

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Egyrészt hol van a "belső eszköz" határa, másrészt meg nem teljesen mindegy, hogy mennyi kell és milyen gyorsan.

Ja, és tőlem kiindulhatunk abból, hogy van egy karakterláncod nullánál több karakterrel, de akkor mi van? Ez most egyáltalán jó vagy rossz hír? :-)

---
Science for fun...

Elsore nekem is az ugrott be, hogy wc -c -vel megszamolni a byte-okat, de szerintem az mar kulso eszkoznek minosul. Gondolom ugy ertette a kollega hogy nem hiv meg semmilyen kulso programot, dash built-in megoldas kell.
____________________
echo crash > /dev/kmem

igen, úgy :)

Jó. :-)

Akkor a következő kérdésem, hogy van-e ennek a kikötésnek valami értelme is, vagy csak úgy brahiból csinálod?

Nekem ugyanis többször kellett már ilyesmit megoldanom, de eszembe nem jutott volna shellből csinálni. Megírtam C-ben. Volt vagy 10 sor.

---
Science for fun...

az adott környezetben csak egy dash áll rendelkezésre, de az alábbiak alapján már nézegetem, hogy a printf ${#} kifejezésben milyen lehetőségeim vannak :)

Perl, Python, Lua egyike sincs?

$ python3
>>> import random
>>>
>>> random.randint(1,90)
5
>>> random.randint(1,90)
33

$ perl -e 'print int(rand(89)+1)'

#!/usr/bin/lua

math.randomseed(os.time())
print (math.random(1,90))
print (math.random(1,90))

Illetve ha dash helyett bash is jó: echo $RANDOM

köszi a kérdés kimondottan arra e helyzetre készült, mikor csak dash van, de már megvan a megoldás alább, persze P* nyelvekbe már én is tudok könnyen :)

hát a mennyiségről és sebességről csak annyit tudok mondani, hogy amit a vas ki tud tolni, szóval lehet csak arra gondolni, hogy "szeretnék egy véletlen számot" :)

tehát az itt az igazi kérdés először, hogy egyáltalán hogy tudok persze, lehetőleg gyorsan 1 darab véletlen számot kapni a nélkül, hogy lehetőleg bármilyen egyéb telepített külső futtatható segédprogramot meg kéne hívnom

Esetleg?
read DATA < /dev/urandom && printf "%i\n" ${#DATA}
____________________
echo crash > /dev/kmem

ez jó indulásnak tűnik nekem, nézem! köszi! :-)

Milyen véletlen szám kell és milyen eloszlásban?

0 és 1 közötti lebegőpontos, 0 és valamilyen MAX közötti egész?

Egyenletes eloszlás? Normális eloszlás? Poisson-eloszlás?

Nagyon aluldefiniált a probléma.

0 és 1 is elég lenne (nem vagyok matekos, de közben elkezdek utánanézni az eloszlás definícióinak...)

Mármint elég neked egy random bit?
Na, az tök jó, csak milyen eloszlásban?

Az kell neked, hogy várhatóan ugyanannyi 0 legyen, mint 1? Ez egy egyenletes eloszlás.

Vagy az is jó, ha 1 millióból 400 ezerszer 0 van, és 600 ezerszer 1? Ez is egy értelmes diszkrét eloszlás.
Esetleg más kell?
Sokféle diszkrét eloszlás van, a nekik megfelelő tulajdonságokkal.
http://www.ngkszki.hu/~trembe/nev_eloszl/nev_eloszl.htm
https://math.bme.hu/~nandori/Virtual_lab/stat/dist/Discrete.xhtml

igen, az egyenletesre gondoltam, csak nem tudtam, mi a "normális" :)

A /dev/random, /dev/urandom random byte-ot ad neked vissza, karakteres eszköz. Ezt olvashatod, és megnézheted az első bitjét például, ha random bitet akarsz.
Viszont ez nem biztos, hogy teljesen jó lesz neked, megpróbáltam utánanézni, de sehol nem specifikált, hogy a /dev/{u}random milyen eloszlású véletlent generál, ez azért egy picit aggasztó.

na, de hogy nézem meg az első bitet?

most itt tartok:

sh -c 'while read c</dev/urandom; do printf "${#c} "; done' # :)

Ha jó a páros/páratlan vizsgálat eredménye 0 és 1 generálására, akkor valami ilyesmi: echo $(expr $n % 2)

ja persze, csak expr nincs a dash-ban ...

let "b = $n % 2"
echo "$b"

De aritmetikai kifejezés kiértékelés igen. Szóval echo $(( kifejezés ))
Mondjuk ha nem csak abba az irányba menne a dash, hogy elérje a POSIX-ot, hanem már odaért volna, akkor azt mondtam volna, hogy echo $RANDOM

=====
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?

Mondjuk ez egyben elony is. Ami dash alatt jo, az random un*x random shelljeben is futni fog :)
____________________
echo crash > /dev/kmem

Naív ;)

$ bash -c 'test -n "$BASH" && echo ${BASH_VERSINFO[0]}'
4
$ dash -c 'test -n "$BASH" && echo ${BASH_VERSINFO[0]}'
$

Csakhogy NetBSD default sh-ja azt mondja erre, hogy 'Syntax error: Bad substitution'.

POSIX szerint dash-nak és NetBSD sh-nak is igaza van :)

szerk, latom netbsd sh. Hm, kosz a tippet, ranezek. Egy kivetelnek jo lesz ;)
____________________
echo crash > /dev/kmem

Naív++.

Ubuntu 14.04 dash 0.5.7-4ubuntu1, illetve current master-ből (0.5.10.2 után) friss-ropogósan fordított dash:

./src/dash -c 'case 8 in [^0-9]) echo "nem szám" ;; *) echo szám ;; esac' 
nem szám

Ubuntu 16.04 dash 0.5.8-2.1ubuntu2, illetve current masterből ./configure --enable-fnmatch után fordított dash:

/bin/dash -c 'case 8 in [^0-9]) echo "nem szám" ;; *) echo szám ;; esac'
szám

És a releváns POSIX bekezdés.

Akkor hat az a kerdes, van-e olyan shell, amiben ha megirsz valamit, hiba nelkul lefut mas shellek alatt.
Vagy meginkabb az a kerdes, hogy erdemes-e egyaltalan egy limitaltabb funkcionalitassal biro shellben scriptet irni, ha ugyis Linux es bash van mindenhol, vagy ha nem Linux akkor is van/lehet bash.
____________________
echo crash > /dev/kmem

Eleve hol van a bash?
/bin/sh
/bin/bash
/usr/local/bin/bash
?

=====
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?

"Akkor hat az a kerdes, van-e olyan shell, amiben ha megirsz valamit, hiba nelkul lefut mas shellek alatt."

Egyrészt nincs, másrészt meg nem lehet csak a shell-re korlátozni a kérdést, és figyelmen kívül hagyni a scriptből indított sok egyéb programot.

A 0.4.1-es verzióval milyen eredményt kapsz?

A dash git repository-ban nincs 0.4.1 tag, kb. egy perc kereséssel pedig nem találtam máshol...
Feltételezem, hogy azzal is csak a szabványos [!0-9] menne.

Ha jól tudom, akkor ez a verzió kapta meg a dash nevet. :-)

köszi mindkét választ, nagyon értékesek, szerintem meg is leszek, még finomítgatom, köszi! :)

Offtopic, de az echo $(expr ... ) erősen túlbeszélt forma, az expr eleve az stdout-ra ír, szóval csak simán elég az expr ... is ;-)

=====
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?

Páros-páratlanból számolva egyenletes eloszlásnak tűnik:
Zero: 499531; One: 500469;

Nagyobb mintára és többször futtassa az a tesztet, aki nagyon ráér.

sh -c 'while read s; do printf $(( ${#s} % 2 )); done</dev/urandom'

több mindent is megértettem ebből s a segítségetekkel, köszönöm! egyrészt azt, hogy a # a sztring hosszát adja vissza, másrészt megismertem ezt a % jelet az aritmetikai kifejezésben, ami, ha jól értem a paramétere által megadott maradékot adja vissza.

Gyorsnak nem gyors, persze ezzel is tudok kezdeni valamit, de jobban örülnék, ha 100.000 karaktert generálni egy másodperc alatt :))

Megírod c-ben a programot, ami random [1|0] -t ír standart outputra. Vagy az értéket /dev/urandom -ból kiolvasva, vagy a rand() függvényt használva. Az utóbbi gyorsabb.
Néha jól jön az ilyen shell-ben, de nem 100000-res mennyiségben.

-fs-
Az olyan tárgyakat, amik képesek az mc futtatására, munkaeszköznek nevezzük.
Amióta megismerkedtem az Anroidos és IOS-es kacatokkal, azóta a Windows láttán már nem kapok gyomorgörcsöt.

Az urandom értékének beolvasása egy változóban, 100000-szer (i7-4771, 3,5 GHz), mindenféle konvertálás és kiíratás nélkül:

real	1m39,342s
user	1m8,320s
sys	0m34,880s

Komolyan upgrade-elni kellene a gépet, ha ezt dash alatt 1 másodperc alatt akarnám letudni. :-)

$ cat /dev/urandom |head -c 16|hexdump -e '"%03d "'
-1734809013 -502496132 1378839751 1745071248

Ilyesmi kell? Nem is értem mit akarsz ebből kihozni. Az urandomból pszeudórandom számok jönnek eleve bájtonként. Ahány bájtos számot akarsz, annyit olvasol ki. Miért kellene a számokat számmá alakítani, ha már egyszer eleve számok?

mert nincs cat és hexdump csak a dash belső parancsai, de már megvan a megoldás :)

Véletlen szám nem létezik :)