Following your answer, this is a simplified version of your solution:
<?php
//file1
session_start();
$token = uniqid();
$_SESSION['token'] = $token;
?>
<!--page html here-->
<script src="/js.php?t=<?php echo $token;?>"></script>
.
header('Content-Type: application/javascript');
$token = isset($_GET['t'])? $_GET['t'] : null;
if(!isset($_SESSION['token']) || $_SESSION['token'] != $token){
//lets mess with them and inject some random js, ih this case a random chunk of compressed jquery
die('n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)}');
}
//regenerate token, this invalidates current token
$token = uniqid();
$_SESSION['token'] = $token;
?>
$.getScript('js2.php?t=<?php echo $token;?>');
.
<?php
//js2.php
//much the same as before
session_start();
header('Content-Type: application/javascript');
$token = isset($_GET['t'])? $_GET['t'] : null;
if(!isset($_SESSION['token']) || $_SESSION['token'] != $token){
//lets mess with them and inject some random js, ih this case a random chunk of compressed jquery
die('n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)}');
}
unset($_SESSION['token']);
//get actual js file, from a folder outside of webroot, so it is never directly accessable, even if the filename is known
readfile('../js/main.js');
Note the main changes are:
Simplifying the token system. As the token is in the page source, all it needs to do to function is to be unique, attempts to make it 'more secure' with encoding and salts etc do nothing.
The actual js file is saved outside the web root, so its not possable to access directly even if you know the filename
Please note that i still stand by my comment about IP banning bots. This solution will make scraping a lot harder, but not impossible, and could have unforeseen consequences for genuine visitors.