Sunday, February 8, 2015

A New URL

Hey all - I have been able to reacquire one of my domains that were so viciously stolen from me by domain squatters some time ago. So, you can now visit the site using www.joshwieder.net. Keep in mind that all links to joshwieder.blogspot.com will continue to work.

Wednesday, February 4, 2015

Google Maps Javascript API Tutorial is Rubbish

I am working on creating a Google-maps based project. As such, I was using the Google Maps Javascript API Tutorial to activate an API key and create a 'Hello World' style test script.

I continuously received one of the following errors:

Google has disabled use of the Maps API for this application. The provided key is not a valid Google API Key, or it is not authorized for the Google Maps Javascript API v3 on this site. If you are the owner of this application, you can learn about obtaining a valid key here: https://developers.google.com/maps/documentation/javascript/tutorial#api_key

Google has disabled use of the Maps API for this application. See the Terms of Service for more information: http://www.google.com/intl/en-US_US/help/terms_maps.html.

Having not used the API to make a single call, the notion that I had somehow violated the Google TOS was particularly infuriating, as was the notion that I had not enabled the Google Maps API, which I had done, as outlined in the API Tutorial:


The issue, at least in my case, turned out to be the sample code that Google provides in the same tutorial. The sample is as follows:


<html>
<head>
<style type="text/css">
html, body, #map-canvas { height: 100%; margin: 0; padding: 0;}
</style>
<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY" type="text/javascript">
</script>
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: { lat: -34.397, lng: 150.644},
zoom: 8
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas">
</div>
</body>
</html>

In the script above, the developer is prompted to replace API_KEY with their actual API Key. However, this will cause a TOS violation if you have followed the Tutorial. To resolve the issue, add the following to your API Key:

&sensor=false
So the entire line of script, with an actual API Key, would look something like this:

<script src="https://maps.googleapis.com/maps/api/js?key=21a300d4a9a2cf55e4ffac1750acbc01
&sensor=false" type="text/javascript">
This will allow the map to render as described in the tutorial.

Sunday, February 1, 2015

BootChess: The Tiniest Chess Program in Town

Coding hyper-efficient chess programs has been something like a running contest among big time Smarty Pantses with too much time on their hands. For the last 33 years, the record for the smallest version of chess was held by the fabled 1K ZX Chess for the Sinclair ZX81. First published in 1982, 1K ZX had all of the basic chess rules and a opponent loaded into a now-hard-to-imagine 672 bytes of memory. Its publisher, David Horne, would go on to publish the code for the program in a three art Computer Magazine series (the first part of which you can see embedded below:


This is the super-rad David Horne:

david horne joshua wieder bootchess

1K ZX's 33 year reign has just been challenged. The challenger is a program called BootChess, which includes all of the features of 1K ZX with a stunning memory allocation of only 512 bytes. The program was written by Olivier Poudade and Peter Ferrie.

BootChess, Josh Wieder, DOSBox
It was never a very graphic-intensive game, anyway
This is a photo of Peter Ferrie:
Joshua Wieder Peter Ferrie

A photo of Olivier Poudade was not immediately available however this artist's rendition is accurate:

Joshua Wieder Olivier Poudade
Olivier is not, in fact an evil genius. I can't prove it. Yet.
That 512 byte number might be familiar to some readers; it is the exact size of an x86 bootloader (You can take a closer look at the source, in assembler below). There is still a bit of a controversy surrounding the release, as there appears to be a few bugs with BootChess. I personally haven't had a chance to give it a complete test run yet (but I look forward to). Let me know what you think.

;----------RED-SECTOR-INC.-proudly-presents-a-33-year-old-record-:----------
; 468-byte footprint___ _ "...The original chess game in a bootsector"
; / / _____ _ _ _____ _ _ ___ _
; .::. / / / / / / / / / /
; :::: / / ____ .-/ _ ___/-. .-/ _ ___/-. / /__
; :: / \ | | . | | | . | / /
; :: __ _ \ l | | | l | | / ___/
; .::. / / / / | l |_| l | |__/ / ____
; .::::. / __/ `--' `--' / |
; :::::::: / / |
; ___ __ Cl! ___ ___ / ___ _ _ __|
; ___ _ _ / __/_ __ _ _/ _/_ _ /_ / / ___ /__
; /_/ / / / / / / _____/ / / / __/ _ / / /
; .-/ ___/ / /______ / ___\ \___ / / __/
; | / / / | __/ ___ | \ | ___\ \___
; | / ____ | / | | _/ | | \ |
; | /--/ | ___/ | | | | | _/ |
; | | / / :: | ____/ :: | | :: \_____| | |
; |_____/ :: | __/ /_______| /_______| |_______\ | :: \_____|
; /_______| /___ _ /___ _ _ ___\ |_______\
; /___ _ _ ___\ v.02
; BootChess is the smallest computer implementation of chess on any platform
; Chess in a 512-byte x86 boot sector for Windows / Linux / OS X / DOS / BSD
; Coded by Olivier "Baudsurfer/RSi" Poudade with extra help of Peter "QKumba"
; Ferrie. Logo by Frederic "Cleaner/Break" Cambus. (c)2015 WTFPL v2 license.
; ****************** To Mr. Oscar Toledo and others : **********************
; YOU MAY REFACTOR THE RESULT OF OUR WORK (THIS FILE) BUT PLEASE CREDIT US !
; **************************************************************************
; "Fasm BootChess.asm" + "partcopy BootChess.bin 0 200 -f0" = PC floppy boot
;-BootChess.asm-------------------;-----------------------------------------
; gui=0=>no board indexes, x86=1=>boot vs. dos, p2q=1=>queening vs failsafe
gui equ 0 ; gui=1 x86=1 p2q=1 510b+ OK pad OK gui OK vbr- OK queen
x86 equ 0 ; gui=1 x86=1 p2q=0 498b+ OK pad OK gui OK vbr+ NO queen
p2q equ 0 ; gui=1 x86=0 p2q=1 504b NO pad OK gui NO vbr- OK queen
_b equ byte ; gui=1 x86=0 p2q=0 485b NO pad OK gui NO vbr+ NO queen
_w equ word ; gui=0 x86=1 p2q=1 479b+ OK pad NO gui OK vbr- OK queen
_d equ dword ; gui=0 x86=1 p2q=0 481b+ OK pad NO gui OK vbr+ NO queen
_s equ short ; gui=0 x86=0 p2q=1 487b NO pad NO gui NO vbr- OK queen
_f equ far ; gui=0 x86=0 p2q=0 468b NO pad NO gui NO vbr+ NO queen
if x86=1 ; beg of boot vs .com preprocessing
org 7c00h ; std start of bootsector after post
if p2q=0 ; beg clear any start ambiguous segment
jmp _f 0:fix ; 7c0:0000 vs. 0:7c000 cs para fix-up
end if ; end clear any start ambiguous segment
fix:push cs ; if post int 19h isr bootsrap loader
pop ds ; left any bda or shadow segment values
push cs ; then enforce ds=cs=0
pop es ; then enforce es=ds=cs=0
mov aX,13h ; function set vga mode 320x200x256
else ; else if 16-bit binary assume ah=0
org 100h ; start of com binary program ip
mov aL,13h ; function set vga mode 320x200x256
end if ; end of boot vs .com preprocessing
int 10h ; standard bios video api
if gui=1 ; guiimalist no coordinate indexes ?
bf1 equ bf3 ; chess board at end of sector
else ; else show coordinate indexes
bf1 equ bf2 ; chess board at end of sector
end if ; end conditional precompile
brd equ bf1+16 ; chess board at end of sector
mov di,brd ; set physical board index
mov bp,12 ; set 6x8+8 empty sqr mid board lines
call in2 ; pass#1 black "rnbqkbnr" low-caps
push word opn ; pass#2 hi-caps whites & fall-through
rle:lodsb ; al='.'/al=null (fixed length rle)
mov cl,8 ; empty sqr mid board line length
rep stosb ; set one empty sqr mid board line
dec bp ; all empty sqr mid brd lines inited ?
jnz rle ; if not repeat init else bp=0 assumed
mov ah,'A'-'a' ; fall-through pass#2 white hi-caps
in2:mov si,br0 ; si points to endrank "rnbqkbnr" str
if x86=0 ; if .com binary environment ch=0
mov cL,8 ; "rnbqkbnr" endrank str length
else ; assume nothing although tempting
mov cX,8 ; "rnbqkbnr" endrank str length
end if ; end of register ch startup value
in3:lodsb ; read physical board str car
add al,ah ; hi-caps rank 1 / low-caps rank 8
stosb ; write physical board str car
loop in3 ; all "rnbqkbnr" str car written ?
mov cl,8 ; si-;equiv piece vals di-;0x88 brd
rep movsb ; write logical 0x88 board str vals
retn ; return to callers
ge0:mov bx,di ; physical board idx (bx=brd)
mov dh,'1' ; beg white move src rank
ge1:mov dl,'h' ; beg white move src file
ge2:mov [si],dx ; beg white move src str
mov ch,'1' ; beg white move dst rank
ge3:mov cl,'h' ; beg white move dst file
ge4:mov [si+2],cx ; beg white move dst str
pusha ; save all values
call idx ; passive chess coords to linear indexes
jbe mis ; white move src color not conforguig
push bx ; save white move dst idx
call ver ; white move legal chess ?
pop bx ; restore white move dst idx
jc mis ; white move not legal chess
mov di,num+3 ; compare move destination rank in 7dfeh
inc si ; with move source rank in 7dfch
cmpsb ; is taxi distance to topmost bettered ?
jnc wor ; else not getting closer to black king
cmp _b [di],'?' ; does any fallback move exist yet ?
jz lkj ; no, then last valid move good enough
wor:mov aL,_b[si+bx+brd-num-'a'+6]; yes, previous valid legal exist so
dec aL ; only override if it's a capture
js mis ; no, don't want worse taxi distance
mov bx,fs ; it's a capture with piece value=al
cmp bL,aL ; but hightest capture value yet ?
jnc mis ; no, less important opponent piece
max:mov fs,bx ; fs=best move yet in taxi half-ply
lkj:dec si ; realign source index
dec si ; to copy dword bst=dword idx
movsd ; after 4096 tries : move=dword bst
mis:popa ; restore all values
cmp cl,'a' ; end white move dst file ?
loopnz ge4 ; dec white move else next dst file
inc ch ; inc white move dst rank
cmp ch,'9' ; end white move dst rank ?
jnz ge3 ; else next move dst rank
cpx:inc bx ; inc physical board index
dec dx ; dec white move src file
cmp dl,'`' ; end white move src file ?
jnz ge2 ; else next move src file
inc dh ; inc white move src rank
cmp dh,ch ; end white move src rank ? ch=9
jnz ge1 ; else next move src rank
push _d [si+4] ; get best white move found
pop _d [si] ; set it as final white move
val:mov cl,'.' ; valid : empty sqr replaces src piece
call act ; active chess coords to linear indexes
xor bp,3 ; player turn and pawn unidir. delta
jz ge0 ; white turn to play (case best=0)
bla:mov al,'?' ; input str clear pattern
mov di,si ; input str clear pattern (di=num)
mov cx,8 ; input str clear pattern
rep stosb ; input str clear pattern (di=brd)
call key ; get user keyboard input
jbe bla ; black move src color not conforguig
opn:call ver ; di=brd, black move legal chess ?
jc bla ; white move not legal chess
jmp _s val ; validate black move
ver:call idx ; get lin indexes /w implicit passive
xchg bx,dx ; switch bx=dst idx dx=src idx
mov ah,[si+bx+brd-num-'a'+8] ; get piece logical 0x88 brd val...
mov dh,bl ; dh=src idx dl=dst idx
sub dx,"aa" ; get move file zero-based indexes
bsr bx,ax ; scan for 1st bit set (si=idx+10)
movsx bx,[si+bx-10-num+tab] ; bl=moved piece type idx (bh=0)
mov cx,_w [si+bx-num+tab] ; piece type deltas cl=repeats ch=num
sahf ; set piece logical 0x88 brd val
jnp sp1 ; branch if piece not pawn (bit#4!=1)
jc sp2 ; branch if pawn prev moved (bit#0=1)
sp1:jns sp3 ; branch if piece not king (bit#7!=1)
sp2:mov cl,1 ; override repeat if piece pawn or king
sp3:jnp sp4 ; branch if piece not pawn (bit#4!=1)
add bx,bp ; pawn player turn unidirection mutex
sp4:inc bx ; advance piece type struct field ptr
and ah,11111100b ; isolate piece bitmask only
vl1:push cx ; save piece type deltas
mov al,dh ; load start dst idx val
inc bx ; advance piece type struct field ptr
vl2:add al,[si+bx-num+tab] ; add this piece delta to dst idx val
xchg aL,bL ; base reg=dst idx val and preserved
mov ch,[si+bx+brd-num+8] ; read projected dst square val
xchg aL,bL ; base reg=piece type struct field ptr
cmp al,dl ; wanted move found (src+delta(s)=dst) ?
jnz dif ; different than requested move
sam:sahf ; get piece logical 0x88 brd val in flgs
jnp yes ; branch if piece is not pawn (bit#2=0)
test [si+bx-num+tab],1 ; pawn piece delta parity=diag vs. vert
jz ord ; branch if pawn piece moving vert
test ch,ch ; pawn piece vert move=;eating ?
jz _s bad ; illegal chess move is a miss
yes:pop cx ; correct entry sp and disregard count
retn ; return to caller(s)
ord:test ch,ch ; pawn piece vert move=;no eating ?
jz yes ; no eating=;empty dst sqr else illegal
dif:sahf ; store piece nature in flags register
jnp skp ; not pawn piece so skip direction test
test [si+bx-num+tab],1 ; pawn piece delta parity=diag vs. vert
jnz bad ; diagonal pawn move is illegal
skp:test ch,ch ; else skipping over dst square val ?
jnz bad ; projected dst sqr val is not empty
sahf ; get piece logical 0x88 brd val in flgs
jz x88 ; branch if piece is queen (bit#6=1)
jna bad ; branch if piece is not knight(bit#4=0)
x88:test al,88h ; ch=0 dst out of physical board limits?
loopz vl2 ; else cont if delta repeats remain
bad:pop cx ; restore piece type deltas
dec ch ; all possible delta nums verified ?
jnz vl1 ; if not then cont next delta type
nok:stc ; else return /w no match flg set
retn ; return to caller
key:call prt ; refresh screen to account input echo
xor bx,bx ; bx=str idx=odd/even/alpha/num mutex
kbd:cbw ; fun blocking wait for keystroke (ah=0)
int 16h ; std bios keybd api (ah=scan al=ascii)
esc:dec ah ; was esc key pressed to quit ?
jnz car ; else default process key input
xit:if x86=1 ; if x86 boot context environment
int 19h ; exit through bootstrap to reboot cpu
else ; else if .com 16-bit binary
int 20h ; dos 1+ - terguiate program
end if ; end of exit methods (os load or shell)
car:mov [bx+si],al ; sav ascii val to move string (si=num)
prt:pusha ; save game state snapshot
cwd ; curs location dx=(0,0)=(row,column)
mov ax,1301h ; function ega write str write mode 1
mov bl,7 ; page 0 grey car attrib matching tty
mov cl,8 ; src str lngth (curs updated horiz)
if gui=1 ; minimalist no coordinate indexes ?
mov bp,bf1 ; es:bp is "abcdefgh" ptr
else ; else show coordinate indexes
mov bp,bf1+16 ; es:bp is dontcare ptr
end if ; end of conditional precompile
lns:int 10h ; standard bios video api
add bp,16 ; bp=para step siz separating strings
if gui=1 ; minimalist no coordinate indexes ?
push ax ; save old bios video api func params
mov ax,0e39h ; function teletype outp car=rank '9'
sub al,dh ; decrement right handside rank value
int 10h ; standard bios video api
pop ax ; restore old bios video api fx params
end if ; end of conditional precompile
if gui=1 ; minimalist no coordinate indexes ?
cmp dh,cl ; src str total (curs updated vert)
inc dh ; preemptive off-by-one allows 9 verts
else ; else show coordinate indexes
inc dh ; non-preemptive off-by-one for 8 verts
cmp dh,cl ; src str total (curs updated vert)
end if ; end of conditional precompile
jc lns ; all 9 brd gui row strings printed ?
mov bp,si ; 10th row tail bp=move coords, cl=8
int 10h ; standard bios video api
popa ; restore game state snapshot
inc bx ; test if any more keys ?
cmp bl,4 ; frFR format input string
jc kbd ; else continue input
idx:loop idx ; ch=0 passive call load src/dst lin idx
act:mov si,num ; reinit si to point to coord input str.
mov bx,[si] ; bx=src coord (pass#1)
cbw ; empty sqr val in logical 0x88 board
call put ; place param passed as fun pass#1
mov dx,[si+2] ; bx=dst idx dx=src idx
xchg bx,dx ; fall-through for second pass
push word mat ; test for checkmate and conforguig
put:xchg ax,bx ; bx|dx=[num+di]+16*((8-'0')-[num+di+1])
aad -10h ; shl ah,4/sub al,ah/xor ah,ah
add al,80h ; bx|dx=al-640%256-16*ah
xchg ax,bx ; bx|dx=al+128-16*ah
jcxz sim ; active call request or simulation ?
if p2q=1 ; standard non-failsafe queening
cmp _b [si+3],'8' ; validated dst rank is top-most ?
jz qq ; if so then promote pawn to queen
cmp _b [si+3],'1' ; validated dst rank is bottom-most ?
jnz prm ; if not no pawn queening promotion
qq: sahf ; store piece nature in flag register
jnp prm ; no pawn queening promotion
xor ah,01000110b ; transform p to promoted queen
inc cx ; queen promotion p2q or P2Q
end if ; end of conditional queening
prm:xchg ah,[si+bx+brd-num-'a'+8] ; update piece logical 0x88 board val
xchg cl,[si+bx+brd-num-'a'] ; update piece physical board ascii val
or ah,1 ; update piece moved once (bit#0)
sim:retn ; return to caller(s)
mat:sahf ; catured piece king and mate ?
js xit ; if piece is king then game is over
call chk ; move src color conforguig ?
jnz nok ; move src color not conforguig
chk:xchg bx,dx ; src idx <- dst idx
mov al,[si+bx+brd-num-'a'] ; pass#1:src idx pass#2:dst idx di=brd
xor _b [si+len-num],8 ; self-modif 8/26 val=[1;8]/[a(A);z(Z)]
mov cl,-'a' ; assert black piece car interval
test bp,bp ; test whose turn it is to play
jnz lim ; assert white piece car interval
mov cl,-'A' ; al=ascii value cl=-(lower boundery)
lim:xadd al,cl ; tmp=al+cl cl=al al=tmp +fall-trough
db 0d4h ; aam <self-modified value>
len:db 12h ; ah=al/8 al%=8
mov al,cl ; al=restored ascii value
test ah,ah ; set/clear zf=0 success zf=1 failure
retn ; return to caller(s) nb: destroys ah
tab db p-tab,r-tab,n-tab,b-tab ; piece type mov offset array
db q-tab,q-tab ; note original 1K ZX Chess q=k trick
br0 db "rnbqkbnr",8,16,32,64,128 ; end rank pattern + beg piece values
db 32,16,8,'p',4,'.',0,'.',0 ; end piece values + beg mid board reps
db '.',0,'.',0,'P',4 ; ... end mid board reps
p db 2,3,-10h,-15,-17,10h,15 ; bit#2 pf=04 p[6]=r[0] overlay
r db 17,4,10h,-1h,-10h ; bit#3 ??=08 r[5]=n[0] overlay
n db 1,8,1fh,21h,12h,-0eh,-1fh ; bit#4 af=16 n[9]=b[0] overlay
db -21h,-12h ; ... end of knight moves list
b db 0eh,4,-0fh,11h,-11h ; bit#5 ??=32 b[5]=q[0] overlay
q db 0fh,8 ; bit#6 zf=64 k=q except k[0]=1
bf2 db 10h,11h,0fh,1h,-10h ; queen/king moves list and gui base
db -11h,-0fh,-1h ; ... end of queen/king moves list
if gui=1 ; minimalist no coordinate indexes ?
bf3 db "abcdefgh" ; gui file index string
end if ; end of conditional queening
num db "e2e4" ; hardcoded Ruy Lopez opening
if x86=1 ; if x86 boot environment
if p2q=0 ; if vbr signature failsafe
times 510-($-$$) db 0 ; nul padding if necessary
org 7df0h ; boot signature vbr/mbr standard offset
sig db 55h,0aah ; magic number no-endian boot signature
else ; no vbr signature failsafe
times 512-($-$$) db 0 ; nul padding if necessary
end if ; end of conditional padding
end if ; end of conditional failsafe signature
view raw BootChess.asm hosted with ❤ by GitHub

The Latest Not-So-Subtle Threat to Tech Companies Using Encryption

This time the kneecap-breaker is Stewart Baker, former counsel general of the NSA and assistant secretary for the Department of Homeland Security (currently counsel with Steptoe & Johnson LLP).

Baker claims that Blackberry (AKA RIM) should blame its use of strong encryption for its poor market performance. Specifically:
He claimed that by encrypting user data Blackberry had limited its business in countries that demand oversight of communication data, such as India and the UAE and got a bad reception in China and Russia. “They restricted their own ability to sell. We have a tendency to think that once the cyberwar is won in the US that that is the end of it - but that is the easiest war to swim.”
Of course, Baker makes no mention of the iPhone snatching up corporate mobile market-share, or tiny changes in the phone market like, I dunno, the implementation of the Android OS. But who cares about little fish like that when the United Arab Emirates is at stake?

Baker's statements are not competent when viewed as economic analysis. It might seem like Baker is carrying water for the intelligence community, but maybe its as simple as having an atrophied thinking cap from a lifetime in "government service"?

Uploading HTML forms to Amazon S3 using PHP

Dynamically uploading information to S3 can be a bit challenging to do initially, particularly in PHP where a lot of the documentation is either really new or really old.

Amazon has a PHP SDK, which is available as either a .phar file or can be installed using Composer. That's cool for building a new project, but what if you have a pre-existing project or form and just want to be able to dump the text output to S3?

I've put together some code at Github that will take care of that issue. The only requirement is PHP and an Amazon S3 account.

Download or clone the files here: https://github.com/jwieder/s3-http-php-form

Your Amazon access keys and other configuration are stored in a single configuration file. Just fill out your login info into the configuration file and include the php form where you need it as outlined in the README.md file and you should be all set!