import 'dart:convert';

//data [0-256)
//return [0-256)
List<int> encrypt(List data, String key) {
  var mapTable = getSortTable(key);
  List<int> result = [];
  for(var i=0; i<data.length; i++){
    var targetVal = mapTable[data[i]];
    //print("${data[i]}==>${targetVal}");
    result.add(targetVal);
  }

  return result;
}

//data base64
//return base64
List<int> decrypt(List data, String key) {
  var mapTable = getSortTableDec(key);
  
  List<int> result = [];

  for(var i=0; i<data.length; i++){
    var targetVal = mapTable[data[i]];
    result.add(targetVal);
  }

  return result;
}

Map getSortTableDec(String key) {
  var mapTable = getSortTable(key);
  var mapTableDec = Map<int, int>();
  mapTable.forEach((key, value){
    mapTableDec[value] = key;
  });

  return mapTableDec;
}

Map getSortTable(String key) {
  var mapTable = Map<int, int>();
  for(var i=0; i<=0xff; i++) {
    mapTable[i] = i;
  }
  
  List<int> bytes = utf8.encode(key);

  for(var i=0; i<0xff; i++) {
    var val = randNum(bytes, i + 10, i + 1, 0xff + 1);
    int tmpVal = mapTable[val]!;
    mapTable[val] = mapTable[i]!;
    mapTable[i] = tmpVal;
  }

  return mapTable;
}

//[start, end)
int randNum(List<int> bytes, int index, int start, int end) {
  int total = 0;
  for (var i=0; i<bytes.length; i++) {
    total += bytes[i] + index;
  }

  if(total < 0) {
    total = total * -1;
  }

  var result = start + (total % (end - start));

  return result;
}

