Created
November 5, 2012 09:45
-
-
Save waynebaby/4016356 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
----------------------------------Unsafe Code--------------------- | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Runtime.InteropServices; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace WordsRandom | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
do | |
{ | |
var str = Console.ReadLine(); | |
RandomWords(str); | |
Console.WriteLine(str); | |
} while (true); | |
} | |
public struct Pair<TX, TY> | |
{ | |
public TX X; | |
public TY Y; | |
} | |
public struct Pair | |
{ | |
public static Pair<TX, TY> Create<TX, TY>(TX x, TY y) | |
{ | |
return new Pair<TX, TY> { X = x, Y = y }; | |
} | |
} | |
static Random _rnd = new Random(); | |
static HashSet<char> _splitChars = new HashSet<char> { '\'', '.', ' ', '\r', '\t', '\n' }; | |
static unsafe void RandomWords(string content) | |
{ | |
var spaceMarks = System.Linq.Enumerable.Concat(" ", content).Concat(" ") | |
.Select((c, i) => Pair.Create(c, i-1)) | |
.Where(p => _splitChars.Contains(p.X)) | |
.Select(p => p.Y); | |
var segs = spaceMarks | |
.Zip(spaceMarks.Skip(1), (x, y) => Pair.Create(x+ 2, y-x-3)) //对空格进行两两配对计算混淆的起止坐标 | |
.Where(p => p.Y > 1); //没有内容可混淆的过滤掉 | |
fixed (char* ptr = content) | |
{ | |
foreach (var seg in segs) | |
{ | |
RandomArea(seg, ptr); | |
} | |
} | |
} | |
static unsafe public void RandomArea(Pair<int, int> marks, char* array) | |
{ | |
// var chars = new char[segment.Count]; | |
int Offset = marks.X; | |
int Count = marks.Y; | |
for (int i = 0; i < Count; i++) | |
{ | |
char tempChar; | |
var remains = Count - i;//随着循环进行,可以取出的范围减少 | |
var last = remains + Offset - 1; | |
//随机取出一个 和剩余没有抽取的最后元素交换。最后的元素们就是结果 | |
var chosen = _rnd.Next(0, remains) + Offset; | |
tempChar = array[chosen]; | |
array[chosen] = array[last]; | |
array[last] = tempChar; | |
} | |
} | |
} | |
} | |
-----------------------------------Safe Managed code------------------------ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace WordsRandom | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
do | |
{ | |
var str = Console.ReadLine(); | |
Console.WriteLine(RandomWords(str)); | |
} while (true); | |
} | |
public struct Pair<TX, TY> | |
{ | |
public TX X; | |
public TY Y; | |
} | |
public struct Pair | |
{ | |
public static Pair<TX, TY> Create<TX, TY>(TX x, TY y) | |
{ | |
return new Pair<TX, TY> { X = x, Y = y }; | |
} | |
} | |
static Random _rnd = new Random(); | |
static HashSet<char> _splitChars = new HashSet<char> { '\'', '.', ' ', '\r', '\t', '\n' }; | |
static public string RandomWords(string content) | |
{ | |
var charArray = new Char[content.Length + 2]; | |
content.CopyTo(0, charArray, 1, content.Length); | |
charArray[0] = ' '; | |
charArray[charArray.Length - 1] = ' '; | |
//标记所有空格 | |
var spaceMarks = charArray | |
.Select((c, i) => Pair.Create(c, i)) | |
.Where(p => _splitChars.Contains(p.X)) | |
.Select(p => p.Y); | |
var segs = spaceMarks | |
.Zip(spaceMarks.Skip(1), (x, y) => Pair.Create(x, y)) //对空格进行两两配对 | |
.Select(p => Pair.Create(p.X + 2, p.Y - p.X - 3)) //计算混淆的起止坐标 | |
.Where(p => p.Y > 1) //没有内容可混淆的过滤掉 | |
.Select(p => new ArraySegment<Char>(charArray, p.X, p.Y)); | |
foreach (var seg in segs) | |
{ | |
RandomArea(seg); | |
} | |
return new string(charArray, 1, charArray.Length - 2); | |
} | |
static public void RandomArea(ArraySegment<char> segment) | |
{ | |
// var chars = new char[segment.Count]; | |
for (int i = 0; i < segment.Count; i++) | |
{ | |
char tempChar; | |
var remains = segment.Count - i;//随着循环进行,可以取出的范围减少 | |
var last = remains + segment.Offset - 1; | |
//随机取出一个 和剩余没有抽取的最后元素交换。最后的元素们就是结果 | |
var chosen = _rnd.Next(0, remains) + segment.Offset; | |
tempChar = segment.Array[chosen]; | |
segment.Array[chosen] = segment.Array[last]; | |
segment.Array[last] = tempChar; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment