How do I protect phone number from bots - php

I want a phone number which display on public page will be protected. Example converts phone number characters to HTML entities and bots can't grab the number in plain text. Let me know the trick.

This is a...passing thought, though I'm not sure how practical it would be:
<span class="protectedNumber" title="01234567890"></span>
css:
span.protectedNumber:before {
content: "Phone number: " attr(title);
}
JS Fiddle demo.
Edited, in response to 'cross browser?' question in comments, to add a jQuery option to assist with those browsers that don't have the ability to deal with css-generated content:
$(document).ready(
function(){
$('.protectedNumber').each(
function(){
$(this).text('Phone number: ' + $(this).attr('title'));
});
});

some ideas
display the phone number as an image
use javascript to create and display the phone number
throw in html tags in between the numbers (e.g. [span]) that visually makes no difference but makes it more difficult for the bot to recognize the phone number

Try writing the number using ASCII:
http://www.ascii.cl/htmlcodes.htm
<html>
<body>112</body>
</html>

The first thing I'd think of is render an image.
Use Javascript to obfuscate
Obfuscate using a php function

Sure just print the phone number using words instead of numbers...

Create an image of the number, this will foil MOST bots, but some may have OCR, so obfuscate it.
ie: Good:
Better:
The 2nd 1 better because like Captcha, the background contains "noise" that makes it hard for OCR enabled bots to harvest, but is as readable to human eyes..
The hard solution would be use Captcha or a simple PHP script to create the picture on the fly, but in most cases, unless you using alot of different #'s the "better" solution above easiest and quickest method, can do easy even in simple program like Paint in 5 min.
For the visually impaired, include a small link to an audio file (mp3) of you saying the number, if it linked properly, and accordingly, it should work.

Related

Formatting fraction fir display

I'm formatting fraction with MathJax and are having problem displaying it properly.
$disp = '<h1>$${{10 \over 9 }} of 99 $$</h1><br>';
echo $disp;
For some reason, i cannot get a space before and after the word 'of'. Any pointers is greatly appreciated. Thanx in advance.
This is better handled as
$disp = '<h1>$${10 \over 9}\text{ of }99$$</h1><br>';
as the accepted answer does not get the font or spacing for "of" correct.
It also seems that you may be using <H1> simply to get a larger size. If so, that is bad practice, as <H1> is a structural element indicating a top-level heading (not a layout element for a larger size). Unless this expression really is a top-level heading, you should not use <H1> for it. For example, people using assistive technology like screen readers often are given a list of the headings so they can quickly jump to the important starting points of your page, so if you make all your expressions be headings, that will complicate their already difficult task of navigating your page.
Layout should be controlled by CSS, so you could use a <div> with a class around your display math if you want to size it. Or you could use one of the TeX macros like \Large or \LARGE to make the math larger from within the expression. But don't use a heading indicator unless it really is the start of a new section of your page.
Here are some examples:
.dmath {
font-size: 200%;
}
<script src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-chtml.js"></script>
Bad:
<h1>$${10 \over 9} of 9$$</h1>
Better using CSS and <code>\text{}</code>:
<div class="dmath">
$${10 \over 9}\text{ of }9$$
</div>
Better using <code>\LARGE</code> and <code>\text{}</code>:
$$\LARGE {10 \over 9}\text{ of }9$$
<br><br><br><br>
Usually, \ keep the space between letters.
$disp = '<h1>$${{10 \over 9 }}\ of\ 99 $$</h1><br>';
Reference - Spacing in math mode

PHP preg_replace markdown issue - detecting duplicates

In a project I am building I would like to use markdown as follows
*text* = <em>text</em>
**text** = <strong>text</strong>
***text*** = <strong><em>text</em><strong>
As those are the only three markdown formats I require, I would like to remain lightweight and avoid importing the entire PHP markdown library as that would introduce features I do not require and create issues.
So I have been trying to build some simple regex replaces. Using preg_replace I run:
'/(\*\*\*)(.*?)\1/' to '<strong><em>\2</em></strong>'
'/(\*\*)(.*?)\1/' to '<strong>\2</strong>'
'/(\*)(.*?)\1/' to '<em>\2</em>',
And this works great! em, bold, and the combo all work fine...
But if the user makes a mistake or enters to many stars, everything breaks.
i.e.
****hello**** = <strong><em><em>hello</em></strong></em>
*****hello***** = <strong><em><strong>hello</em></strong></strong>
******hello****** = <strong><em></em></strong>hello<strong><em></em></strong>
etc
When ideally it would create
****hello**** = *<strong><em>hello</em></strong>*
*****hello***** = **<strong><em>hello</em></strong>**
******hello****** = ***<strong><em>hello</em></strong>***
etc
Ignoring the un-required stars (so it would become clear to the user they made a mistake, and more importantly, the rendered HTML remains valid).
I presume there must be some way to modify my regex to do this but I cannot for the life of my work it out, even after a whole day trying!
I would also be happy with the result of
******hello****** = <strong><em>hello</em></strong>
So please, can anybody help me?
Also please consider uneven stars. In this case the below scenario would be ideal.
***hello* = **<em>hello</em>
And the time when a star should be part of the body and not detected, such as if a user inputs:
'terms and conditions may apply*'
or
'I give the film 5* out of 10'
Many many thanks
Try different capturing pattern (match anything except * one or more times),
'/(\*\*\*)([^*]+)\1/'

United Kingdom (GB) postal code validation without regex

I have tried several regexes and still some valid postal codes sometimes get rejected.
Searching the internet, Wikipedia and SO, I could only find regex validation solutions.
Is there a validation method which does not use regex? In any language, I guess it would be easy to port.
I supose the easiest would be to compare against a postal code database, yet that would need to be maintained and updated periodically from a reliable source.
Edit: To help future visitors and keep you from posting any more regexes, here's a regex which I have tested (as of 2013-04-24) to work for all postal codes in Code Point (see #Mikkel Løkke's answer):
//PHP PCRE (it was on Wikipedia, it isn't there anymore; I might have modified it, don't remember).
$strPostalCode=preg_replace("/[\s]/", "", $strPostalCode);
$bValid=preg_match("/^(GIR 0AA)|(((A[BL]|B[ABDHLNRSTX]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[HNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTY]?|T[ADFNQRSW]|UB|W[ADFNRSV]|YO|ZE)[1-9]?[0-9]|((E|N|NW|SE|SW|W)1|EC[1-4]|WC[12])[A-HJKMNPR-Y]|(SW|W)([2-9]|[1-9][0-9])|EC[1-9][0-9])[0-9][ABD-HJLNP-UW-Z]{2})$/i", $strPostalCode);
I'm writing this answer based on the wiki page.
When checking on the validation part, it seems that there are 6 type of formats (A = letter and 9 = digit):
AA9A 9AA AA9A9AA AA9A9AA
A9A 9AA Removing space A9A9AA order it AA999AA
A9 9AA ------------------> A99AA -------------> AA99AA
A99 9AA A999AA A9A9AA
AA9 9AA AA99AA A999AA
AA99 9AA AA999AA A99AA
As we can see, the length may vary from 5 to 7 and we have to take in account some special cases if we want to.
So the function we are coding has to do the following:
Remove spaces and convert to uppercase (or lower case).
Check if the input is an exception, if it is it should return valid
Check if the input's length is 4 < length < 8.
Check if it's a valid postcode.
The last part is tricky, but we will split it in 3 sections by length for some overview:
Length = 7: AA9A9AA and AA999AA
Length = 6: AA99AA, A9A9AA and A999AA
Length = 5: A99AA
For this we will be using a switch(). From now on it's just a matter of checking character by character if it's a letter or a number on the right place.
So let's take a look at our PHP implementation:
function check_uk_postcode($string){
// Start config
$valid_return_value = 'valid';
$invalid_return_value = 'invalid';
$exceptions = array('BS981TL', 'BX11LT', 'BX21LB', 'BX32BB', 'BX55AT', 'CF101BH', 'CF991NA', 'DE993GG', 'DH981BT', 'DH991NS', 'E161XL', 'E202AQ', 'E202BB', 'E202ST', 'E203BS', 'E203EL', 'E203ET', 'E203HB', 'E203HY', 'E981SN', 'E981ST', 'E981TT', 'EC2N2DB', 'EC4Y0HQ', 'EH991SP', 'G581SB', 'GIR0AA', 'IV212LR', 'L304GB', 'LS981FD', 'N19GU', 'N811ER', 'NG801EH', 'NG801LH', 'NG801RH', 'NG801TH', 'SE18UJ', 'SN381NW', 'SW1A0AA', 'SW1A0PW', 'SW1A1AA', 'SW1A2AA', 'SW1P3EU', 'SW1W0DT', 'TW89GS', 'W1A1AA', 'W1D4FA', 'W1N4DJ');
// Add Overseas territories ?
array_push($exceptions, 'AI-2640', 'ASCN1ZZ', 'STHL1ZZ', 'TDCU1ZZ', 'BBND1ZZ', 'BIQQ1ZZ', 'FIQQ1ZZ', 'GX111AA', 'PCRN1ZZ', 'SIQQ1ZZ', 'TKCA1ZZ');
// End config
$string = strtoupper(preg_replace('/\s/', '', $string)); // Remove the spaces and convert to uppercase.
$exceptions = array_flip($exceptions);
if(isset($exceptions[$string])){return $valid_return_value;} // Check for valid exception
$length = strlen($string);
if($length < 5 || $length > 7){return $invalid_return_value;} // Check for invalid length
$letters = array_flip(range('A', 'Z')); // An array of letters as keys
$numbers = array_flip(range(0, 9)); // An array of numbers as keys
switch($length){
case 7:
if(!isset($letters[$string[0]], $letters[$string[1]], $numbers[$string[2]], $numbers[$string[4]], $letters[$string[5]], $letters[$string[6]])){break;}
if(isset($letters[$string[3]]) || isset($numbers[$string[3]])){
return $valid_return_value;
}
break;
case 6:
if(!isset($letters[$string[0]], $numbers[$string[3]], $letters[$string[4]], $letters[$string[5]])){break;}
if(isset($letters[$string[1]], $numbers[$string[2]]) || isset($numbers[$string[1]], $letters[$string[2]]) || isset($numbers[$string[1]], $numbers[$string[2]])){
return $valid_return_value;
}
break;
case 5:
if(isset($letters[$string[0]], $numbers[$string[1]], $numbers[$string[2]], $letters[$string[3]], $letters[$string[4]])){
return $valid_return_value;
}
break;
}
return $invalid_return_value;
}
Note that I've not added British Forces Post Office and non-geographic codes.
Usage:
echo check_uk_postcode('AE3A 6AR').'<br>'; // valid
echo check_uk_postcode('Z9 9BA').'<br>'; // valid
echo check_uk_postcode('AE3A6AR').'<br>'; // valid
echo check_uk_postcode('EE34 6FR').'<br>'; // valid
echo check_uk_postcode('A23A 7AR').'<br>'; // invalid
echo check_uk_postcode('A23A 7AR').'<br>'; // invalid
echo check_uk_postcode('WA3334E').'<br>'; // invalid
echo check_uk_postcode('A2 AAR').'<br>'; // invalid
As supplied by the UK government.
(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY])))) [0-9][A-Z-[CIKMOV]]{2})
I've built London only postcode based apps using the postcodes I got from HERE. But to be honest, even with London postcodes only, you need a lot more storage than necessary. Sure, the idea is trivial.
Store the postcodes, take the user input or whatever, and see if you get a match. But you are complicating the solution far more than you think. I HAD to use actual postcodes to achieve what I wanted, but for simple validation purposes, as hard as "maintaining" a regex is, storing tens of thousands or hundreds of thousands(if not more) and validating more or less in real-time is a far more difficult task.
If a mini distributed service sounds like a more efficient solution than a regex, go for it, but I'm sure it isn't. Unless you need geo-spatial querying of your own data against UK postcodes or things like that, I doubt DB storage is a feasible solution. Just my 2 cents.
Update
According to this index, there are 1,758,417 postcodes in the UK. I can tell you I am using a few Mongo clusters (Amazon EC2 High Memory Instances) to provide reliable London only services(indexing only London postcodes), and it's quite a pricy thing, even with basic storage.
Admittedly, the app is performing medium complexity geo-spatial queries, but the storage requirements alone are very expensive and demanding.
Bottom line, just stick to regex and be done with it in two minutes.
Im looking at the Postcodes in United Kingdom link in wikipedia right now.
http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom
The Validation section lists six formats with a combination of letters and numbers. Then there's more information in the notes below that. The first thing that I would try is a BNF type grammar with a tool like GoldParserBuilder. You could describe the basic formats in a more readable format, with efficient parser and lexer automatically generated. In the past, I've successfully used such tools to avoid writing huge, ugly regexes.
From that point, the program has a properly formatted zip code of a known type. At this point, the specific numbers or letters might violate something. Each type of zip code can have a function programmed to look for violations of that specific type. The final product will consist of an automatically generated parser that passes unvalidated, but structured/identified, zip codes to a dedicated validation function. You can then refactor or optimize from there.
(You can also use the grammar itself to enforce or disallow certain literals and combinations. Whatever is more readable or comprehensible for you. Different people gravitate toward different ends of these things.)
Here's a page highlighting advantages of GOLD Parsing System.You can use any you like: I just promote this one b/c it's good at its job and has steadily improved over many years.
http://www.goldparser.org/about/why-use-gold.htm
I would think the RegEX, while long-winded would probably be the best solution if all you want to do is validate if something could be a valid UK post code.
If you need absolute data, consider using Ordnance Survey OpenData initiative "Code-Point® Open" dataset, which is a CSV of lots of data points in Great Britain (so not Northern Ireland I'm guessing) one of which is postcode. Be aware that the file is 20MB, so you may have to convert it to a more manageable format.
Regexes are hard to debug, hard to port from one regex flavor to another (silent "errors"), and hard to update.
That is true for most regexes, but why don't you just split it up into multiple parts? You can easily split it into six parts for the six different general rules and maybe even more if you take all of the special cases into account.
Creating a well-commented method of 20 lines with simple regexes is easy to debug (one simple regex per line) and also easy to update. The porting problem is the same, but on the other hand you do not need to use some fancy grammar lib.
Are third party services an option?
http://www.postcodeanywhere.co.uk/address-validation/
GeoNames Database:
http://www.geonames.org/postal-codes/
+1 for the "why care" comments. I have had to use the 'official' regex in various projects and while I have never attempted to break it down, it works and it does the job. I've used it with Java and PHP code without any need to convert it between regex formats.
Is there a reason why you would have to debug it or break it down?
Incidentally, the regex rule used to be found on wikipedia, but it appears to have gone.
Edit: As for the space/no-space debate, the postcode should be valid with or without the space. As the last part of the postcode (after the space) is ALWAYS three digits, it is possible to insert the space manually, which will then allow you to run it through the regex rule.
Take the list of valid postcodes and check if the one entered is in it.

substr and strlen explanation

Ok guys, this question is related to my previous one.
If I have set $textlimit = 500; that will limit my text to 500 characters.
Is there any way to "avoid" text limit, and then onclick function load rest of it?
For example, if I set:
$textpart = substr($fulltext, 0, 400);
$textpart will only contain 400 characters of string.
My question is, how to declare variable, which will contain the rest of the text which is much longer than 500 characters?
Example of variables:
$fulltext //Contains full text, but is limited to 500 characters.
$textpart //Contains part of the text, substr 400 characters out of 500.
$textrest //This variable to "hold" rest of the text, after 400 characters of $textpart.
Like I've asked in previous question, I wanted to make expand and collapse button, I now know how to do that, but I don't know how to divide text.
Form would go like this:
Random text here(400 characters long)
Random image for expand
After declared onclick function I, load rest of the text (Over 500 characters).
Random image for collapse
After declared onclick function collapse and return to previous state - citation 1.
I hope I explained my question the right way. I would really appreciate any kind of help, if I can choose, I would like just basic explanation on how to that, because I want to learn that, not copy/paste solution (it is easier, but I will not learn much).
Thanks in advance.
$textrest = substr($fulltext, 400)
$fulltext = substr($fulltext, 0, 500);
$textpart = substr($fulltext, 0, 400);
$textrest = substr($fulltext,400,strlen ( $fulltext ));
If I understand you correctly you want to show the user an initial page that shows only the first X characters and then show all the characters when the users clicks on the text.
There are three strategies to do this. From easy to hard:
Output the shortened text and include a link that will reload the whole page but with the whole text
Output all the text and use css and JavaScript to hide/show any overflow
Output the shortened text and perform an Ajax call to load the extra characters and append
Options 2 and 3 require the use of client side JavaScript and are therefore not pure PHP solutions.
Option 1 is a matter of adding a $_GET variable, e.g. ?expand=para1, to your url and expanding the text identified in PHP by $_GET['expand'].
Do not make the mistake of thinking PHP is still running on the page in the browser. Only JavaScript can run in the browser on the web page. (Not strictly true I know, but true enough in reality.)

How to make something like stackoverflow's similar title search

*UPDATE:*I've already answered my question. But you can still give me advise and i'll take your answer as selected
NOTE: If you don't need to know what I want to do with the codes, just skip the first several paragraphs and directly see the codes and tell me why they doesn't work without error.
I want to make something like stackoverflow's similar title search when you enter your title in the ask page.
I need to split words to make regex and then search in the database. Since my application is in Chinese(no spaces between each words) and I think splitting chinese into meaningful phrases using PHP is too hard. I have an idea splitting it in the client side using javascript according to chinese IME's characteristic that, for example, if you want to type the word "你好中国" in chinese, people usually type "nihao[space]zhongguo" in IME(note where the space bar is), since '你好'(nihao - hello) is a phrase and '中国'(zhongguo - china) is another. So when people press space bar i record the word he entered before the space and start a timer of 2 seconds , if he or she enters another words clear the timer and continue to record if he or she doesn't, send each words recorded to the server.
Qustion is, is this a good idea? Are there any other convenient way to do this? And why these lines i wrote to test won't work without error.
script:
$(function(){
var i=0;
$('#t').keyup(function(e){
if(e.keyCode==32)
{
eval("a"+i+"=$(this).val()");
i++;
var timer=setTimeout("for(b=0;b<i;b++){alert(eval('a'+b));}",1000);
if($("#t").keydown())
{
clearTimeout(timer);
}
}
})
})
html:
<input id="t"/>
I think i know why it won't work now:
First, i should be a global variable;
Second, the keydown() function should be outside of the keyup(). modified js:
$(function(){
i=0;
timer=null;
$('#t').keyup(function(e){
if(e.keyCode==32)
{
eval("a"+i+"=$(this).val()");
i++;
timer=setTimeout("for(b=0;b<i;b++){alert(eval('a'+b));}",1000)
}
})
if($("#t").keydown())
{
clearTimeout(timer);
}
})
If you have other suggestions on my idea or codes you can still answer this question or i'll select this one after some time.

Categories