Archive for the 'PHP' Category

Discuz! 6.1 用户密码的存放和生成方式

2009-4-12 13:00 | by 2ndboy

  自 Discuz! 6.1 以后,装 Discuz! 就必须安装 UCenter。经过分析,事实上自从跟 UCenter 集成以后,Discuz! 的用户密码就不是存放在 Discuz! 自己的 cdb_members 表里了,而是放在 UCenter 库里的 uc_members 表里。

  Discuz! 目录下的 register.php,其中向 cdb_members 表里插数据时密码的生成方式如下:

  1.  $password = md5( random( 10 ) );
  2.  ?>

只是用一个随机数的 MD5 值填充了用户密码字段,这跟 admin/members.inc.php 里的做法是一样的,根本没有使用用户自己输入的密码(可见即便 hacker 拿到了 Discuz! 库中用户表的数据,也没办法用 MD5 碰撞的方法找出一个可以登录的用户密码)。

  真正的用户密码保存在 UCenter 库的 uc_members 表里,代码在 uc_client/model/user.php 里:

  1.  function add_user($username, $password, $email, $uid = 0)
  2.  {
  3.      $salt = substr(uniqid(rand()), -6);
  4.      $password = md5(md5($password).$salt);
  5.      $sqladd = $uid ? 'uid=\''.intval($uid).'\',' : '';
  6.      //$appid = UC_APPID;
  7.      $this->db->query("INSERT INTO ".UC_DBTABLEPRE."members SET $sqladd username='$username', password='$password', email='$email', regip='".$this->base->onlineip."', regdate='".$this->base->time."', salt='$salt'");
  8.      $uid = $this->db->insert_id();
  9.      $this->db->query("INSERT INTO ".UC_DBTABLEPRE."memberfields SET uid='$uid'");
  10.      return $uid;
  11.  }
  12.  ?>

(UC_DBTABLEPRE 的定义是 define(‘UC_DBTABLEPRE’, ‘`ucenter`.uc_’);)可以看出来,这里的密码生成算法跟生成 UCenter 创始人密码的算法是一样的,都是用一个加扰串结合原始密码的 MD5 再做一次 MD5。

  知道了以上原理,就可以手工对用户名密码做一些处理了。

UCenter 创始人的密码修改

2009-3-26 19:48 | by 2ndboy

  UCenter 创始人密码不是写在数据库里的,而是根据放在 UCenter 安装目录下的 data/config.inc.php 里。基本上,创始人密码是这么产生的:

加密后的密码 = md5( md5( 创始人密码 ) + 加扰串 )

下面是一段重新产生创始人密码的 PHP 代码:

  1. <?php
  2.  $UC_FOUNDERSALT = '加扰串';
  3.  $password = '密码';
  4.  
  5.  $UC_FOUNDERPW = md5( md5( $password ) . $UC_FOUNDERSALT );
  6.  
  7.  echo "define( 'UC_FOUNDERSALT', '$UC_FOUNDERSALT' );\n";
  8.  echo "define( 'UC_FOUNDERPW', '$UC_FOUNDERPW' );";
  9.  ?>

用程序运行后产生的结果替换 config.inc.php 里相应的内容就 ok 了。

基于最近好好学习 Python 才能天天向上的原则,再给出一段多余的 Python 实现:

  1. import hashlib
  2.  
  3.  def md5( data ):
  4.      m = hashlib.md5()
  5.      m.update( bytes( data, 'GB2312' ) )
  6.      return( m.hexdigest() )
  7.  
  8.  UC_FOUNDERSALT = '加扰串'
  9.  password = '密码'
  10.  
  11.  print( "define( 'UC_FOUNDERSALT', '%s' );" % UC_FOUNDERSALT )
  12.  print( "define( 'UC_FOUNDERPW', '%s' );" % md5( md5( password ) + UC_FOUNDERSALT ) )

写了个处理照片的 PHP 程序

2008-4-23 14:16 | by 2ndboy

  最近工作日上班,晚上还要做饭,周末抓紧时间游历湾区,所以少有时间写技术话题,今天来写一个:)

  在 Blog 上贴图的时候比较喜欢处理成自己喜欢的风格,但是手工做起来比较麻烦,也不去找什么工具软件啦,晚上自己用 PHP 写了一个,看代码:

  1.  $file   = 'test.jpg'// 需要进行处理的照片
  2.  $string = 'Night';     // 写在照片下方的文字
  3.  $font   = 'C:/Windows/Fonts/verdana.ttf'// 文字使用的字体
  4.  
  5.  $img    = imagecreatefromjpeg( $file );
  6.  $width  = imagesx( $img );
  7.  $height = imagesy( $img );
  8.  
  9.  if( $width > $height )
  10.  {
  11.      $new_width = 500// 宽度大于高度时,新的宽度值
  12.      $new_height = ( $height / $width ) * $new_width;
  13.  }
  14.  else
  15.  {
  16.      $new_height = 500// 高度大于宽度时,新的高度值
  17.      $new_width = ( $width / $height ) * $new_height;
  18.  }
  19.  
  20.  $new_img = imagecreatetruecolor( $new_width, $new_height );
  21.  
  22.  imagecopyresampled( $new_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height )// 缩放
  23.  
  24.  //
  25.  // 画透明白边
  26.  //
  27.  $white = imagecolorallocatealpha( $new_img, 255, 255, 255, 55 );
  28.  imagefilledrectangle( $new_img, 0, 0, $new_width - 1, 9, $white );      // up
  29.  imagefilledrectangle( $new_img, 0, 10, 10, $new_height - 30, $white )// left
  30.  imagefilledrectangle( $new_img, $new_width - 10, 10, $new_width - 1, $new_height - 30, $white ); //right
  31.  imagefilledrectangle( $new_img, 0, $new_height - 29, $new_width - 1, $new_height - 1, $white )// bottom
  32.  
  33.  $fs = imagettfbbox( 18, 0, $font, $string );
  34.  $fs_width = $fs[4] - $fs[6];
  35.  $fs_height = $fs[3] - $fs[5];
  36.  
  37.  // 在最下面写字
  38.  $blue = imagecolorallocatealpha( $new_img, 0, 0, 255, 55 );
  39.  imagettftext( $new_img, 18, 0, ( $new_width - $fs_width ) / 2, ( $new_height - 29 ) + ( ( 30 - $fs_height ) / 2 ) + 18, $blue, $font, $string );
  40.  
  41.  imagejpeg( $new_img, 'new_test.jpg' );
  42.  ?>

  简单的说,这个程序可以把数码相机拍的任意大小的照片缩放到长边 500px,在四周加一个半透明白框,最后在下面居中用 verdana 标注文本。这里贴的是核心代码,加些外围代码用起来会更方便些:D

  最后贴一张今晚站在阳台上拍的夜景,用上面贴的程序处理过:
Night

用 PHP 查找 workspace 里 project 的依赖关系

2008-2-18 22:15 | by 2ndboy

  有了之前写的那个 Ruby 程序,早前用 PHP 实现的版本就算作古啦,放在这里分享一下:

  1.  $dsw = 'C:/test/test.dsw'// Modify the content before running
  2.  $data = file_get_contents( $dsw );
  3.  
  4.  preg_match( '{(.*(?:/|\\\\)).*}', $dsw, $match );
  5.  $basePath = $match[1];
  6.  
  7.  preg_match_all( '{Project: "([^"]*)"="?([^"]*)"? - }', $data, $matches );
  8.  
  9.  $projects = array();
  10.  for( $i = 0; $i < count( $matches[1] ); $i++ )
  11.  {
  12.      $projectname = $matches[1][$i];
  13.      $projects[$projectname] = array();
  14.      $projects[$projectname]['dsp'] = $matches[2][$i];
  15.  
  16.      $data = file_get_contents( $basePath . $projects[$projectname]['dsp'] );
  17.  
  18.      // Get project type
  19.      preg_match( '{# TARGTYPE ".*" 0x(\d+)}', $data, $match );
  20.      switch( $match[1] )
  21.      {
  22.          case '0101': $projects[$projectname]['extName'] = '.exe'; break// Win32 (x86) Application
  23.          case '0102': $projects[$projectname]['extName'] = '.dll'; break// Win32 (x86) Dynamic-Link Library
  24.          case '0103': $projects[$projectname]['extName'] = '.exe'; break// Win32 (x86) Console Application
  25.          case '0104': $projects[$projectname]['extName'] = '.lib'; break// Win32 (x86) Static Library
  26.          default: print_r( $match );
  27.      }
  28.  
  29.      // Get output filename
  30.      $result = preg_match_all( '{/out:"[^"]*(?:/|\\\\)([^"]*\.[^"]*)"}', $data, $matches2 );
  31.      if( $result >= 2 )
  32.      {
  33.          $projects[$projectname]['outDebug']   = strtolower( $matches2[1][0] );
  34.          $projects[$projectname]['outRelease'] = strtolower( $matches2[1][1] );
  35.      }
  36.      else if( 1 == $result )
  37.      {
  38.          $projects[$projectname]['outDebug']   = strtolower( $matches2[1][0] );
  39.          $projects[$projectname]['outRelease'] = strtolower( $matches2[1][0] );
  40.      }
  41.      else  // 0
  42.      {
  43.          $projects[$projectname]['outDebug']   = strtolower( $projectname . $projects[$projectname]['extName'] );
  44.          $projects[$projectname]['outRelease'] = strtolower( $projectname . $projects[$projectname]['extName'] );
  45.      }
  46.  
  47.      // Get all libs
  48.      $result = preg_match_all( '{# ADD LINK32 ([^/]*)}', $data, $matches2 );
  49.      if( $result >= 2 )
  50.      {
  51.          $projects[$projectname]['linkDebug']   = strtolower( $matches2[1][0] );
  52.          $projects[$projectname]['linkRelease'] = strtolower( $matches2[1][1] );
  53.      }
  54.      else if( 1 == $result )
  55.      {
  56.          $projects[$projectname]['linkDebug']   = strtolower( $matches2[1][0] );
  57.          $projects[$projectname]['linkRelease'] = strtolower( $matches2[1][0] );
  58.      }
  59.      else  // 0
  60.      {
  61.          $projects[$projectname]['linkDebug']   = '';
  62.          $projects[$projectname]['linkRelease'] = '';
  63.      }
  64.  }
  65.  
  66.  foreach( $projects as $key => $value )
  67.  {
  68.      if( '.lib' == $value['extName'] )
  69.          continue;
  70.  
  71.      echo '<br/>Project: ' . $key . '<br/>';
  72.      foreach( $projects as $key2 => $value2 )
  73.      {
  74.          if( strstr( $value['linkDebug'], $value2['outDebug'] ) )
  75.              echo $key2 . '<br/>';
  76.      }
  77.  }
  78.  ?>

  今天早上尝试了一把 RubyScript2Exe,很好很强大!就一个 .rb 文件,用它把需要转成 EXE 的 Ruby 脚本跑一遍就可以生成一个可以完全脱离 Ruby 环境单独运行的可执行程序。把之前写的那个 Ruby 程序转换了一下,现在完全可以实用啦!

用 GD 库显示音标的尝试

2007-12-2 19:51 | by 2ndboy

  想在图片里显示音标,很自然的想到用金山词霸里面的“Kingsoft phonetic”字体,但是后来才发现这个看似 easy 的问题不是那么简单,在这里分享一下如何用 PHP 的 GD 库在图片上显示音标。

如下程序理论上可以显示出 apple 这个单词的音标来(音标部分文字复制自金山词霸):

  1.  $img = imagecreatetruecolor( 240, 320 );
  2.  $white = imagecolorallocate( $img, 255, 255, 255 );
  3.  imagettftext( $img, 8, 0, 10, 10, $white, "Ksphonet.ttf", "5Apl" );
  4.  imagepng( $img );
  5.  ?>

但是运行以后显示出来的都是方块,如果用 HTML 来调用这个字库就没问题:

  1. <span style="font-family:Kingsoft Phonetic">5Apl</span>

上面那段 PHP 代码是在 PHP 里使用 TrueType 字体的常规套路,之前曾经屡试不爽,所以只能理解为金山的这个音标字体文件比较特殊了。Google 了一把找到了解决方案:国际音标的对应字体选用及四种输入方法。使用微软自带的“Lucida Sans Unicode”字体就能搞定。

问题是我用的音标文本都是从金山词霸里复制出来的,如果直接用 Lucida Sans Unicode 字体来显示这些内容的话会原样输出,所以我做了一个金山词霸音标文本到 Lucida Sans Unicode 音标文本的转换函数:

  1.  function KP2LSU( $code )
  2.  {
  3.      $newCode = '';
  4.      $len = strlen( $code );
  5.      for( $i = 0; $i < $len; ++$i )
  6.      {
  7.          switch( $code[$i] )
  8.          {
  9.              case '5':
  10.                  $newCode .= '\'';
  11.                  break;
  12.              case '7':
  13.                  $newCode .= ',';
  14.                  break;
  15.              case 'A':
  16.                  $newCode .= '&#230;';
  17.                  break;
  18.              case 'B':
  19.                  $newCode .= '&#593;';
  20.                  break;
  21.              case 'C':
  22.                  $newCode .= '&#596;';
  23.                  break;
  24.              case 'E':
  25.                  $newCode .= '&#477;';
  26.                  break;
  27.              case 'F':
  28.                  $newCode .= '&#643;';
  29.                  break;
  30.              case 'N':
  31.                  $newCode .= '&#331;';
  32.                  break;
  33.              case 'Q':
  34.                  $newCode .= '&#652;';
  35.                  break;
  36.              case 'V':
  37.                  $newCode .= '&#658;';
  38.                  break;
  39.              case 'W':
  40.                  $newCode .= '&#415;';
  41.                  break;
  42.              case 'Z':
  43.                  $newCode .= '&#603;';
  44.                  break;
  45.              case'^':
  46.                  $newCode .= 'g';
  47.                  break;
  48.              default:
  49.                  $newCode .= $code[$i];
  50.                  break;
  51.          }
  52.      }
  53.  
  54.      return( $newCode );
  55.  }
  56.  ?>

这样一来上面那段显示 apple 音标的程序就可以这样写啦:

  1.  $img = imagecreatetruecolor( 240, 320 );
  2.  $white = imagecolorallocate( $img, 255, 255, 255 );
  3.  imagettftext( $img, 8, 0, 10, 10, $white, "Lucida_Sans_Unicode.ttf", KS2LSU( "5Apl" ) );
  4.  imagepng( $img );
  5.  ?>