2012-05-30 4 views
1

문자열을 정수로 변환하는 여러 가지 방법이 있습니다. 즉 고려되어야 할 수 있도록문자열을 int로 보안 방식으로 변환하는 가장 좋은 방법은 무엇입니까?

$someString = substr($input, strripos($input, "_") + 1); 
$i = $someString + 0; 
$i = (int) $someString; 
$i = intval($someString); 

$someString는 사용 입력에서 비롯됩니다. 어느 옵션이 “이 더 좋고 ”이 좋을지 또는 가장 부작용이 있습니까? (즉, 성능 측면에서 보면 보안과 관련하여)

$input1_abcd_1 또는 1_abcd_2과 비슷합니다. 이 예에서는 abcd을 제외하고는 꽤 고정 된 —입니다. 이 입력은 라디오 버튼에서 제공되지만 원하는 경우 언제든지 사용자가 데이터를 변경할 수 있습니다. 따라서 악성 데이터를 고려해야합니다.

답변

2

를 사용할 수있는 숫자입니다. 성능 차이는 미미합니다. 그러나 어떤 경우에는 정수가 생성되지 않을 수도 있습니다.

예를 들어, $input = '19.99';으로 지정하십시오.

$i = $someString + 0; // $i = 19.99 

다른 두 케이스는 동일하지만 $i = intval($someString);$i = (int) $someString; 평균보다 약 56 % 더 빠르게. 둘 다 밀리 초 단위로 실행되기 때문에 상당한 차이가 나지 않는 한 성능 차이는 일반적으로 무시할 수 있습니다. 보안의 문제에

$i = (int) $someString;  // $i = 9 
$i = intval($someString); // $i = 9 

: 당신이 $input은 항상 특정 형태로 될 것으로 예상되는 경우 (예를 들어,#는 # _xxxx_), 당신은 그것을 그 형식 것을 확인해야합니다. Jack ’의 확장 — ’ PHP> = 5.2.0을 사용하는 경우 정규식을 사용하여 입력 형식을 확인할 수 있습니다.

<?php 
$input = '1_abcd_1'; 

// Set the desired format 
$filter_options = array(
    'options' => array(
     // choose a regular expression that matches your format 
     'regexp' => '/^[\d]_[a-z]{4}_[\d]$/' 
    ) 
); 

$format = filter_var($input, FILTER_VALIDATE_REGEXP, $filter_options); 
if ($format !== false) { 
    // process input 
    $someString = substr($format, strripos($format, "_") + 1); 
    $i = (int) $someString; 
    echo '$i = ', $i; 
} else { 
    // Handle invalid format 
    echo 'Malformed data. Potentially malicious'; 
} 
?> 

이 완전히 같은 것들을 거부합니다 : 당연히

0xfe 
bob 
j_xtyz_5 
1_wxyz_22 
21_abcd_1 
1_Abcd_2 

을, 당신은 당신의 요구에 정규 표현식을 조정한다.

은 참조 : 당신이 ’ PHP> = 5.2.0를 사용하지 않는 재, 당신은 preg_match

사용 할 수 있습니다.입력의 형식을 검증 는

<?php 
$input = '1_abcd_2'; 

$valid = preg_match('/^[\d]_[a-z]{4}_[\d]$/', $input); 
if ($valid) { 
    // process input 
    $someString = substr($input, strripos($input, "_") + 1); 
    $i = (int) $someString; 
    echo '$i = ', $i; 
} else { 
    // Handle invalid format 
    echo 'Malformed data. Potentially malicious'; 
} 
?> 

데이터가 변경되었는지 여부를 즉시 알 수 ’들 수 있습니다. 그러면 그에 따라 행동 할 수 있습니다.

+1

재미있는 :-). 'is_numeric()'을 사용하는 Rajan Rawal 제안과 결합 할 것입니다. –

+0

@DaanTimmer no,'is_numeric ('0xfe') == true'는 아마도 당신이 원하는 것이 아닙니다. 만약 정수를 테스트하고 싶다면'filter_var'를 사용할 수 있습니다. –

+0

보안을 확장하기 위해 답을 업데이트했습니다. filter_var @ 잭을 가져와 주셔서 감사합니다. – Herbert

3

필자는 캐스팅 유형이 더 좋으며, $i = (int) $someString;은 분명합니다. 당신이 $ someString에 대해 확인하려면

+0

내가 가장 좋아하는 방법입니다. – jancha

+0

동일하게, 조금 더 철저한 것에 대한 허버트의 대답을 받아 들일 것입니다. 그래도 고마워. –

1

입력이 숫자가 ’ 아무 보안 문제로 캐스팅되고 이후에만

if(is_numeric($someString)){ 
    // proceed your code if $someString is numeric 
}else{ 
    // proceed your code if $someString is not numeric 
} 
+0

그래 폭발 버전에 대해 알아. 참으로 is_numeric 검사를하는 것이 좋습니다. 그리고 데이터베이스 작업은 수행되지 않습니다. 비록 내가했을지라도 나는 PDO를 사용할 것이고 그것은 mysql_real_escape를 필요로하지 않는다. 또한 SQL 인젝션을 중단하지 않습니다. –

+0

미안하지만, 당신이 PDO를 사용하고 있다는 것을 몰랐습니다. 나는 당신이 당신의 질문에 보안 현명한 언급 한대로 방금 언급했다. 고맙습니다. –

+0

방금 ​​수치 값 (explode 대 substr)을 추출하는 두 가지 방법 사이에서 성능 테스트를했고 폭발은 ~ 5 % 느립니다. 각 '기능'을 100000 번 실행했습니다. 그리고 그것은 10 배의 루프에서. 값은 4 %에서 7 % 사이였습니다. 아직도 시간을내어 주셔서 감사합니다. 그리고 먼저 is_numeric을 사용하라는 제안을 좋아합니다. –

관련 문제